【问题标题】:How to access a global variable inside a service?如何访问服务内的全局变量?
【发布时间】:2016-08-24 06:07:02
【问题描述】:

我有两个组件。LoginComponent 和 LandingComponent。验证用户名和密码后,我必须从登录页面路由到登录页面。但是我无法访问作为全局/页面变量的服务内的路由器。它显示错误“TypeError:无法读取属性'路由器'”。

import {Component} from 'angular2/core';
import { RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, Router } from 'angular2/router';
import {LoginService} from './login.service';
import {NgForm} from 'angular2/common';

@Component({
    selector: 'login',
    templateUrl: './app/app-components/login/login.html',
    styleUrls:['./app/app-components/login/login.css'],
    directives: [ROUTER_DIRECTIVES],
    providers:[LoginService]
})
export class LoginComponent {

  //DECLARATIONS
  login={username:"",password:""} ;
  active = true;
  submitted = false;  
  router:Router;

  constructor(private _loginService: LoginService,private _router: Router) {
    this.router = _router;
   }

  onAuthenticate() {
      this.submitted = true;
      this._loginService.Login().then( function (loginValues) {        
          if(loginValues.username=="sampleuser" && loginValues.password=="a"){
            this.router.navigate(['LandingPage']);
          }
          else{
           alert("Invalid Username or Password!!");
          }
      });      
   }  
} 

登录服务

import {Injectable} from 'angular2/core';

@Injectable()
export class LoginService {
    Login(){
    return Promise.resolve(login);
    }
}

var login={
    username:"sampleuser",
    password:"a"
}

【问题讨论】:

  • 你的路由配置在哪里?也许你只是错过了添加它,因为装饰器是在你的 LoginComponent 中导入的

标签: typescript angular angular2-routing angular2-services


【解决方案1】:

您应该在 LoginComponent 中像这样使用arrow-functions

this._loginService.Login().then( (loginValues) => {
    if(loginValues.username=="sampleuser" && loginValues.password=="a"){
        this.router.navigate(['LandingPage']);
    }
    else{
        alert("Invalid Username or Password!!");
    }
}); 

这不会改变函数内部的 this。否则 this 不指向你 LoginComponent 的实例,你的路由器也找不到。

【讨论】:

  • 但我的错误改为:“未捕获(承诺中):组件“LoginComponent”没有路由配置。”
  • @sainu 你在哪里引导你的应用程序?你在哪里有你的路由配置?看看 Günther Zöchbauer 的答案。
【解决方案2】:

你的构造函数中的this.router = _router是错误的

private _router 在您的构造函数中在您的类中创建一个实例变量。因此,要访问它,您必须在构造函数中将 this. 添加到变量 _router 中。

改成

this.router = this._router;

所以构造函数最终会是这样的

constructor(private _loginService: LoginService,private _router: Router) {
   this.router = this._router;
}

【讨论】:

  • 错误是一样的:“TypeError: Cannot read property 'router' of null”
【解决方案3】:

您只能将路由器注入具有路由的组件中。

您可能只需要在根组件(或bootstrap(...))上提供LoginService 以获取共享实例。

可以Router 注入您的LoginService

【讨论】:

    【解决方案4】:

    我看到您将服务定义到登录组件的提供者中:

    @Component({
      selector: 'login',
      templateUrl: './app/app-components/login/login.html',
      styleUrls:['./app/app-components/login/login.css'],
      directives: [ROUTER_DIRECTIVES],
      providers:[LoginService] // <-------
    })
    export class LoginComponent {
      (...)
    }
    

    如果落地组件是子组件,则共享同一个实例,否则不共享。

    为了能够共享同一个实例,您需要在引导应用程序时指定服务:

    bootstrap(AppComponent, [LoginService]);
    

    并从登录服务提供商处移除该服务:

    @Component({
      selector: 'login',
      templateUrl: './app/app-components/login/login.html',
      styleUrls:['./app/app-components/login/login.css'],
      directives: [ROUTER_DIRECTIVES],
    })
    export class LoginComponent {
      (...)
    }
    

    这是 Angular2 中分层注入器的工作方式。有关更多详细信息,您可以查看以下问题:

    【讨论】:

      猜你喜欢
      • 2013-12-25
      • 2016-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-30
      • 2012-06-04
      • 2012-10-11
      • 1970-01-01
      相关资源
      最近更新 更多