TypeError: Cannot read property '_router' of null in NativeScript
TypeError: Cannot read property '_router' of null in NativeScript
我正在使用 NativeScript+AngularJS2+TypeScript 开发 android 应用程序。按照他们的文档 - http://docs.nativescript.org/angular/tutorial/ng-chapter-0 .
成功登录后用户需要重定向到 List
页面时卡住了。现在关注他们的路由部分 - http://docs.nativescript.org/angular/tutorial/ng-chapter-3#35-routing
根据他们的文件做了一切。这是我的代码 -
app.component.ts
import {ListPage} from "./pages/list/list.component";
import {Component} from "@angular/core";
import {RouteConfig} from "@angular/router-deprecated";
import {NS_ROUTER_DIRECTIVES, NS_ROUTER_PROVIDERS} from "nativescript-angular/router";
import {LoginPage} from "./pages/login/login.component";
@Component({
selector: "main",
directives: [NS_ROUTER_DIRECTIVES],
providers: [NS_ROUTER_PROVIDERS],
template: "<page-router-outlet></page-router-outlet>"
})
@RouteConfig([
{ path: "/Login", component: LoginPage, name: "Login", useAsDefault: true },
{ path: "/List", component: ListPage, name: "List" }
])
export class AppComponent {}
user.service.ts
import {Injectable} from "@angular/core";
import {User} from "./user";
import {ConfigService} from "../config";
import firebase = require("nativescript-plugin-firebase");
@Injectable()
export class UserService {
register(user: User, config: ConfigService) {
console.log('Email entered : '+user.email);
console.log('Password entered : '+user.password);
console.log("API url going to use is : "+config.apiUrl);
firebase.init(<any>{
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.createUser({
email: user.email,
password: user.password
}).then(
function (response) {
console.log(response);
return response;
}
)
}
login(user: User, config: ConfigService) {
firebase.init({
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.login({
type: firebase.LoginType.PASSWORD,
email: 'eddyverbruggen@gmail.com',
password: 'firebase'
}).then(
function (response) {
console.log(response);
return response;
}
)
}
}
login.component.ts
import {Router} from "@angular/router-deprecated";
import {Component} from "@angular/core";
import {User} from "../../shared/user/user";
import {UserService} from "../../shared/user/user.service";
import {ConfigService} from "../../shared/config";
import {HTTP_PROVIDERS} from "@angular/http";
import firebase = require("nativescript-plugin-firebase");
@Component({
selector: "my-app",
providers: [UserService, HTTP_PROVIDERS,ConfigService],
templateUrl: "pages/login/login.html",
styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginPage {
user: User;
isLoggingIn = true;
config:any;
constructor(private _router: Router, private _userService: UserService) {
this.user = new User();
this.config = new ConfigService();
}
submit() {
if (this.isLoggingIn) {
this.login();
} else {
this.signUp();
}
}
login() {
var result = this._userService.login(this.user,this.config);
result.then(
function (result) {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]);
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
signUp() {
var result = this._userService.register(this.user,this.config);
result.then(
function (result) {
// dialogs.alert({
// title: "User created",
// message: "userid: " + result.key,
// okButtonText: "Nice!"
// })
console.log('User Object Info : '+JSON.stringify(result));
console.log('User Created with user id - '+result.key);
alert("Your account was successfully created.");
this.toggleDisplay();
},
function (errorMessage) {
// dialogs.alert({
// title: "No user created",
// message: errorMessage,
// okButtonText: "OK, got it"
// })
console.log('No user created. Got error message insted - '+errorMessage);
alert("Unfortunately we were unable to create your account.")
}
);
}
toggleDisplay() {
this.isLoggingIn = !this.isLoggingIn;
}
}
除了从文件 this._router.navigate(["List"]);
执行 login.component.ts
时一切正常,我收到以下错误
JS: EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property '_router' of null
无法理解错误到底是什么。
此致
我预计此问题与上下文范围问题有关。我认为您应该先尝试捕获示波器,然后再进入您的示波器。我通常将其存储在一个名为 that
的变量中,请参见下文(并查看评论):
login() {
var result = this._userService.login(this.user,this.config);
var that = this; //store the current context
result.then(
function (result) { //context (this has changed)
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
that._router.navigate(["List"]); //reference _router from the original scope
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
是的,您可以像 George Edwards 指出的那样动态绑定 this
。另一种选择是使用箭头函数,它允许您在函数内保留调用者的范围,这样您就不需要总是记住写 var that = this
.
login() {
var result = this._userService.login(this.user,this.config);
result.then(
// Within the arrow function 'this' now refers to the lexical context rather than changing depending upon how the function is called.
(result) => {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]); //reference _router from the original scope
},
// Arguably clearer
(errorMessage) => {
console.log("Login Error");
console.log(errorMessage);
}
);
}
我正在使用 NativeScript+AngularJS2+TypeScript 开发 android 应用程序。按照他们的文档 - http://docs.nativescript.org/angular/tutorial/ng-chapter-0 .
成功登录后用户需要重定向到 List
页面时卡住了。现在关注他们的路由部分 - http://docs.nativescript.org/angular/tutorial/ng-chapter-3#35-routing
根据他们的文件做了一切。这是我的代码 -
app.component.ts
import {ListPage} from "./pages/list/list.component";
import {Component} from "@angular/core";
import {RouteConfig} from "@angular/router-deprecated";
import {NS_ROUTER_DIRECTIVES, NS_ROUTER_PROVIDERS} from "nativescript-angular/router";
import {LoginPage} from "./pages/login/login.component";
@Component({
selector: "main",
directives: [NS_ROUTER_DIRECTIVES],
providers: [NS_ROUTER_PROVIDERS],
template: "<page-router-outlet></page-router-outlet>"
})
@RouteConfig([
{ path: "/Login", component: LoginPage, name: "Login", useAsDefault: true },
{ path: "/List", component: ListPage, name: "List" }
])
export class AppComponent {}
user.service.ts
import {Injectable} from "@angular/core";
import {User} from "./user";
import {ConfigService} from "../config";
import firebase = require("nativescript-plugin-firebase");
@Injectable()
export class UserService {
register(user: User, config: ConfigService) {
console.log('Email entered : '+user.email);
console.log('Password entered : '+user.password);
console.log("API url going to use is : "+config.apiUrl);
firebase.init(<any>{
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.createUser({
email: user.email,
password: user.password
}).then(
function (response) {
console.log(response);
return response;
}
)
}
login(user: User, config: ConfigService) {
firebase.init({
persist: true, // Allow disk persistence. Default false.
url: config.apiUrl
}).then(
function (instance) {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
return firebase.login({
type: firebase.LoginType.PASSWORD,
email: 'eddyverbruggen@gmail.com',
password: 'firebase'
}).then(
function (response) {
console.log(response);
return response;
}
)
}
}
login.component.ts
import {Router} from "@angular/router-deprecated";
import {Component} from "@angular/core";
import {User} from "../../shared/user/user";
import {UserService} from "../../shared/user/user.service";
import {ConfigService} from "../../shared/config";
import {HTTP_PROVIDERS} from "@angular/http";
import firebase = require("nativescript-plugin-firebase");
@Component({
selector: "my-app",
providers: [UserService, HTTP_PROVIDERS,ConfigService],
templateUrl: "pages/login/login.html",
styleUrls: ["pages/login/login-common.css", "pages/login/login.css"]
})
export class LoginPage {
user: User;
isLoggingIn = true;
config:any;
constructor(private _router: Router, private _userService: UserService) {
this.user = new User();
this.config = new ConfigService();
}
submit() {
if (this.isLoggingIn) {
this.login();
} else {
this.signUp();
}
}
login() {
var result = this._userService.login(this.user,this.config);
result.then(
function (result) {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]);
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
signUp() {
var result = this._userService.register(this.user,this.config);
result.then(
function (result) {
// dialogs.alert({
// title: "User created",
// message: "userid: " + result.key,
// okButtonText: "Nice!"
// })
console.log('User Object Info : '+JSON.stringify(result));
console.log('User Created with user id - '+result.key);
alert("Your account was successfully created.");
this.toggleDisplay();
},
function (errorMessage) {
// dialogs.alert({
// title: "No user created",
// message: errorMessage,
// okButtonText: "OK, got it"
// })
console.log('No user created. Got error message insted - '+errorMessage);
alert("Unfortunately we were unable to create your account.")
}
);
}
toggleDisplay() {
this.isLoggingIn = !this.isLoggingIn;
}
}
除了从文件 this._router.navigate(["List"]);
执行 login.component.ts
时一切正常,我收到以下错误
JS: EXCEPTION: Error: Uncaught (in promise): TypeError: Cannot read property '_router' of null
无法理解错误到底是什么。
此致
我预计此问题与上下文范围问题有关。我认为您应该先尝试捕获示波器,然后再进入您的示波器。我通常将其存储在一个名为 that
的变量中,请参见下文(并查看评论):
login() {
var result = this._userService.login(this.user,this.config);
var that = this; //store the current context
result.then(
function (result) { //context (this has changed)
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
that._router.navigate(["List"]); //reference _router from the original scope
},
function (errorMessage) {
console.log("Login Error");
console.log(errorMessage);
}
);
}
是的,您可以像 George Edwards 指出的那样动态绑定 this
。另一种选择是使用箭头函数,它允许您在函数内保留调用者的范围,这样您就不需要总是记住写 var that = this
.
login() {
var result = this._userService.login(this.user,this.config);
result.then(
// Within the arrow function 'this' now refers to the lexical context rather than changing depending upon how the function is called.
(result) => {
console.log("Login Successs");
// the result object has these properties: uid, provider, expiresAtUnixEpochSeconds, profileImageURL, token
var response = JSON.stringify(result);
console.log('Login Response : '+response);
// Route to list page
this._router.navigate(["List"]); //reference _router from the original scope
},
// Arguably clearer
(errorMessage) => {
console.log("Login Error");
console.log(errorMessage);
}
);
}