使用 AngularFire 和 Firebase 的 Ionic2 错误:未捕获(承诺):这是空的
Ionic2 Error using AngularFire and Firebase: Uncaught (in promisse): This is null
我目前正在学习 Ionic2 和 Angular,并且正在尝试使用 Firebase 作为应用程序的数据库。我要做的第一件事是使用 AngularFire 通过 Firebase 电子邮件身份验证登录。代码如下:
login.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Home } from '../../home/home';
import { SignUp } from '../signup/signup'
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2'
@Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class Login {
constructor(public navCtrl: NavController, public af: AngularFire) {
}
public loginWithEmail(username: string, password: string) {
this.af.auth.login({
email: username,
password: password,
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password,
}).then(function() {
this.navCtrl.setRoot(Home);
})
}
}
login.html
...
<ion-list>
<ion-item>
<ion-label floating>Email</ion-label>
<ion-input type="text" [(ngModel)]="userName"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Senha</ion-label>
<ion-input type="password" [(ngModel)]="password"></ion-input>
</ion-item>
<ion-item>
<button ion-button block (click)="loginWithEmail(userName, password)">Login</button>
</ion-item>
</ion-list>
...
但是,当我点击按钮并调用 loginWithEmail()
方法时,出现了以下错误:
Uncaught (in promise): TypeError: this is null
Login.prototype.loginWithEmail/<@http://localhost:8100/build/main.js:83566:13
O</g</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:9653
NgZone.prototype.forkInnerZoneWithAngularBehavior/this.inner<.onInvoke@http://localhost:8100/build/main.js:37511:28
O</g</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:9591
O</d</e.prototype.run@http://localhost:8100/build/polyfills.js:3:7000
h/<@http://localhost:8100/build/polyfills.js:3:4659
O</g</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:10273
NgZone.prototype.forkInnerZoneWithAngularBehavior/this.inner<.onInvokeTask@http://localhost:8100/build/main.js:37502:28
O</g</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:10201
O</d</e.prototype.runTask@http://localhost:8100/build/polyfills.js:3:7618
i@http://localhost:8100/build/polyfills.js:3:3700
我做错了什么?
好吧,我刚刚找到了让它工作的方法:我刚刚更改了:
(在 login.ts 上)
这个:
.then(function() {
this.navCtrl.setRoot(Home);
})
对此:
.then(() => this.navCtrl.setRoot(Home))
但我仍然不知道为什么它以这种方式工作而不是另一种方式...有人可以解释一下吗?
But I still don't know why it works that way and not in the other...
could someone explain me?
答案是因为Arrow functions。当在像 function(){...}
这样的函数中使用 this
关键字时,this
关键字引用函数本身(并且 navCtrl
未在该函数中定义)。
箭头函数最重要的方面之一是
An arrow function expression has a shorter syntax than a function
expression and does not bind its own this, arguments, super, or
new.target.
所以当在 () => {...} 中使用 this
关键字时,它仍然会引用组件实例(它定义了 navCtrl
属性) , 所以一切都按预期工作。
我目前正在学习 Ionic2 和 Angular,并且正在尝试使用 Firebase 作为应用程序的数据库。我要做的第一件事是使用 AngularFire 通过 Firebase 电子邮件身份验证登录。代码如下:
login.ts
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Home } from '../../home/home';
import { SignUp } from '../signup/signup'
import { AngularFire, AuthProviders, AuthMethods } from 'angularfire2'
@Component({
selector: 'page-login',
templateUrl: 'login.html'
})
export class Login {
constructor(public navCtrl: NavController, public af: AngularFire) {
}
public loginWithEmail(username: string, password: string) {
this.af.auth.login({
email: username,
password: password,
},
{
provider: AuthProviders.Password,
method: AuthMethods.Password,
}).then(function() {
this.navCtrl.setRoot(Home);
})
}
}
login.html
...
<ion-list>
<ion-item>
<ion-label floating>Email</ion-label>
<ion-input type="text" [(ngModel)]="userName"></ion-input>
</ion-item>
<ion-item>
<ion-label floating>Senha</ion-label>
<ion-input type="password" [(ngModel)]="password"></ion-input>
</ion-item>
<ion-item>
<button ion-button block (click)="loginWithEmail(userName, password)">Login</button>
</ion-item>
</ion-list>
...
但是,当我点击按钮并调用 loginWithEmail()
方法时,出现了以下错误:
Uncaught (in promise): TypeError: this is null
Login.prototype.loginWithEmail/<@http://localhost:8100/build/main.js:83566:13
O</g</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:9653
NgZone.prototype.forkInnerZoneWithAngularBehavior/this.inner<.onInvoke@http://localhost:8100/build/main.js:37511:28
O</g</t.prototype.invoke@http://localhost:8100/build/polyfills.js:3:9591
O</d</e.prototype.run@http://localhost:8100/build/polyfills.js:3:7000
h/<@http://localhost:8100/build/polyfills.js:3:4659
O</g</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:10273
NgZone.prototype.forkInnerZoneWithAngularBehavior/this.inner<.onInvokeTask@http://localhost:8100/build/main.js:37502:28
O</g</t.prototype.invokeTask@http://localhost:8100/build/polyfills.js:3:10201
O</d</e.prototype.runTask@http://localhost:8100/build/polyfills.js:3:7618
i@http://localhost:8100/build/polyfills.js:3:3700
我做错了什么?
好吧,我刚刚找到了让它工作的方法:我刚刚更改了:
(在 login.ts 上)
这个:
.then(function() {
this.navCtrl.setRoot(Home);
})
对此:
.then(() => this.navCtrl.setRoot(Home))
但我仍然不知道为什么它以这种方式工作而不是另一种方式...有人可以解释一下吗?
But I still don't know why it works that way and not in the other... could someone explain me?
答案是因为Arrow functions。当在像 function(){...}
这样的函数中使用 this
关键字时,this
关键字引用函数本身(并且 navCtrl
未在该函数中定义)。
箭头函数最重要的方面之一是
An arrow function expression has a shorter syntax than a function expression and does not bind its own this, arguments, super, or new.target.
所以当在 () => {...} 中使用 this
关键字时,它仍然会引用组件实例(它定义了 navCtrl
属性) , 所以一切都按预期工作。