常见问题
http://ionicframework.com/docs/v2/faq/
如果在本页没有找到解决方案,请查看Ionic Forums或加入Ionic Worldwide Slack Channel,获取社区的帮助。
添加第三方库
您可以从NPM给Ionic2项目添加大多数第三方库。例如,让我们添加MomentJs。
npm install moment --save
这样,我们就可以把它import到任何要使用它的地方。
import {Page} from 'ionic-angular';
import * as moment from 'moment';
export class MyClass {
constructor(){
moment("20111031", "YYYYMMDD").fromNow();
}
}
对于TypeScript来说,你可能会得到一个警告:cannot find module 'moment'
。这只是意味着TypeScript不知道什么是MomentJs,因为它是JavaScript。但是我们可以从typings添加一个外部的类型定义。
npm install -g typings
typings search moment
Viewing 5 of 5
NAME SOURCE HOMEPAGE DESCRIPTION VERSIONS UPDATED
moment dt https://github.com/timrwood/moment 1 2016-03-16T15:55:26.000Z
moment npm https://www.npmjs.com/package/moment 1 2016-02-11T00:39:58.000Z
moment-node dt https://github.com/timrwood/moment 1 2016-05-11T04:33:38.000Z
moment-range dt https://github.com/gf3/moment-range 1 2016-03-17T12:06:54.000Z
moment-timezone dt http://momentjs.com/timezone/ 1 2016-03-29T22:03:48.000Z
可以看到对于typings来说有多个源,我们可以从NPM选择一个:typings install npm~moment --save
现在我们的编辑器可以理解MomentJs从而提供代码自动完成功能了。
空白应用
我的App没有任何错误,为什么只显示一个空页面?
这可能由不同的原因导致。如果你在论坛没有找到解决方案,请确保:
- 根
@Compontent
有template
或templateUrl
- 根
@Component
模板有一个带有root
属性的<ion-nav>
标签
<ion-nav [root]="rootPage"></ion-nav>
Directive不工作
为什么我自定义的Component/Directive不工作?
有几个地方你可以检查一下。请确保:
- 如果你的ionic-angular版本低于RC0,请确保在要用该Directive的@Component中的directives数组中包含该Directive。(建议直接使用RC0以后的版本)
- 你的selector没有任何拼写错误
- 你正确的使用selector,作为attribute,element或class
- 你的selector有正确的语法:
- 如果是一个attribute selector,使用
[attr]
- 如果是一个element selector,使用
element
- 如果是一个class selector,使用
.class
这里是一个attribute selector的例子:
- 如果是一个attribute selector,使用
@Directive({
selector: '[my-dir]' // <-- [my-dir] because it's an attribute
}) // Could be my-dir, [my-dir], .my-dir
class MyDir {
constructor() {
console.log("I'm alive!");
}
}
@Component({
// We add my-dir as an attribute to match the directive's selector
template: `<div my-dir>Hello World</div>`,
// Alternatively, if you were attaching the directive to an element it would be:
// template: `<my-dir>Hello World</my-dir>`
// and if you were attaching by class the template would be:
// template: `<div class="my-dir">Hello World</div>`
directives: [MyDir] // <-- Don't forget me! (only if your ionic-angular version is below RC0)
})
class MyPage {}
点击延迟
为什么我的点击事件有延迟?
一般情况下,我们只推荐给普通的可点击的元素添加(click)
事件,如<button>
和<a>
元素。这提升了辅助功能,屏幕阅读器能够告诉使用者哪个元素是可以点击的。
但是你也许需要给一个一般来说不是能点击的元素添加(click)
事件。当你这样做的时候会感觉到从你点击元素到触发事件有300ms的延迟。为了移除这个延迟,你需要给你的元素添加tappable
属性。
<div tappable (click)="doClick()">I am clickable!</div>
常见错误
页面行为异常
Page组件是由NavController载入的,不需要给它们设置selector。如果你在Page组件里放置了selector,有可能会导致错误的动画或应用错误的样式。
错误
@Component({
selector: 'my-page',
template: `
<ion-header>
<ion-navbar>
<ion-title>Login</ion-title>
</ion-navbar>
</ion-header>
<ion-content>Hello World</ion-content>`
})
export class StartPage {}
正确
@Component({
template: `
<ion-header>
<ion-navbar>
<ion-title>Login</ion-title>
</ion-navbar>
</ion-header>
<ion-content>Hello World</ion-content>`
})
export class StartPage {}
忘记给装饰器加括号
Decorator(装饰器)在注解后应该有括号。如:@Injectable()
, @Optional()
, @Input()
等。
@Directive({
selector: 'my-dir'
})
class MyDirective {
// Wrong, should be @Optional()
// @Optional does nothing here, so MyDirective will error if parent is undefined
constructor(@Optional parent: ParentComponent) {}
}
Cordova插件在浏览器中不工作
在你开发的某个阶段你可能会调用Cordova插件,但会得到一个警告:
[Warning] Native: tried calling StatusBar.styleDefault, but Cordova is not available. Make sure to include cordova.js or run in a device/simulator (app.bundle.js, line 83388)
这将在你试图调用原生插件但Cordova不可用的时候发生。还好Ionic Native打印出了一个友好的警告而不是一个错误。
还有一些其他情况,如果插件没有通过Ionic Native调用,插件会输出更加难以理解的警告:
EXCEPTION: Error: Uncaught (in promise): TypeError: undefined is not an object (evaluating 'navigator.camera.getPicture')
如果发生这种情况,请在真实设备或模拟器中测试插件。
Provider的多个实例
略。Angular2正式版后应该不会出现这种问题了。
常见陷阱
Cannot resolve all parameters for ‘YourClass’(?). Make sure that all the parameters are decorated with Inject or have valid type annotations and that ‘YourClass’ is decorated with Injectable.
这个异常表示Angular不知道YourClass构造函数中的一个或多个参数。为了使用依赖注入,Angular需要知道参数的类型才能注入。你应该明确指定参数的类型以便Angular了解。确保:
- 你import了参数的类
- 你已经对参数进行了装饰或指定了它的类型
import {MyService} from 'my-service'; //Don't forget to import me!
@Component({
template: `Hello World`
})
export class MyClass {
// service is of type MyService
constructor(service: MyService) {
}
}
有时候如果代码中有循环引用会导致这个错误。循环引用意味着两个对象彼此依赖,这样就无法对它们进行声明。为了绕过这个问题我们可以使用forwardRef函数来构建Angular。
import {forwardRef} from 'angular2/core';
@Component({
selector: 'my-button',
template: `<div>
<icon></icon>
<input type="button" />
</div>`,
directives: [forwardRef(() => MyIcon)] // MyIcon has not been defined yet
}) // forwardRef resolves as MyIcon when MyIcon is needed
class MyButton {
constructor() {}
}
@Directive({
selector: 'icon'
})
class MyIcon {
constructor(containerButton: MyButton) {} // MyButton has been defined
}
Can’t bind to ‘propertyName’ since it isn’t a known property of the ‘elementName’ element and there are no matching directives with a corresponding property
这将在试图在一个元素上绑定一个不存在的属性的时候发生。如果元素是一个Component或有一个或多个Directive,无论Component还是Directive都没有这个属性。
<!-- div doesn't have a 'foo' property -->
<div [foo]="bar"></div>