如何在Angular 2中定义全局变量,我可以将它们用于模板中的属性绑定?

时间:2016-04-19 10:38:40

标签: data-binding angular

在我的Angular 2(beta 14)应用程序中,我需要跟踪用户登录状态,以便隐藏/显示某些元素。

我遇到的问题是,属性绑定不像我的方式那样工作如下。

我创建了一个用于存储和更新全局变量的类:

应用-global.ts

 import {Injectable} from "angular2/core";

 @Injectable() export class AppGlobals {
   // use this property for property binding
   public isUserLoggedIn: boolean = false;

   setLoginStatus(isLoggedIn){
       this.isUserLoggedIn = isLoggedIn;
   }

   getLoginStatus(){
       return this.isUserLoggedIn;
   } }

在登录组件中,我导入AppGlobals

export class LoginComponent {
    constructor(private _appGlobals: AppGlobals) { }

并按

设置登录状态
  

this._appGlobals.setLoginStatus(真);

在另一个组件中,我像在LoginComponent

中那样注入AppGlobals

我定义了一个类(组件)的属性

  

isLoggedIn:boolean = this._appGlobals.isUserLoggedIn; //我也试过使用getter而不是public属性(见上文)

然后我在组件的模板中使用它来显示/隐藏某个元素:

<!-- here I also tried with {{!isLoggedIn}} but results in a syntax error whereas using [(hidden)] instead of [hidden] changes nothing -->
<div id="some-element" [hidden] = "!isLoggedIn">

最后,当另一个组件(例如LoginComponent)设置登录状态时,绑定有效但没有更新(此组件是AppComponent模板的一部分并显示在每个页面中)。

编辑我尝试应用Gunter的答案,但我收到以下错误:

app/app-globals.ts(10,54): error TS2346: Supplied parameters do not match any signature of call target.
app/app-globals.ts(13,29): error TS2339: Property 'emit' does not exist on type 'BehaviorSubject<boolean>'.

第10行的错误来自[求助]

  

public isUserLoggedIn:BehaviorSubject = new BehaviorSubject()。startWith(false);

并且它显然是由BehaviorSubject引起的,希望 1参数

第13行的错误来自

  

this.isUserLoggedIn.emit(isLoggedIn);

它显然是由于不存在的 emit 方法造成的。

另外,我不明白如何使用AppGlobals以便在另一个组件中绑定自动更新属性(参见编辑前的最后一个示例)

此外,在LoginComponent中,我用 BehaviorSubject 替换了isLoggedIn布尔类型,因为isUserLoggedIn在AppGlobals中有类型BehaviorSubject

  

this._appGlobals.isUserLoggedIn.subscribe(value =&gt; this.isLoggedIn = value);

返回TypeError:

  

分配的表达式类型boolean不能分配给BehaviorSubject类型

2 个答案:

答案 0 :(得分:16)

isLoggedIn: boolean = this._appGlobals.isUserLoggedIn;

是一次性操作,用于复制执行此行时的值。如果您希望传播后续更改,请使用observables

import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/share';
import 'rxjs/add/operator/startWith';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';

@Injectable() 
export class AppGlobals {
// use this property for property binding
  public isUserLoggedIn:BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);

  setLoginStatus(isLoggedIn){
   this.isUserLoggedIn.next(isLoggedIn);
  }
}

并使用它:

export class LoginComponent {
    constructor(private _appGlobals: AppGlobals) {
  this._appGlobals.isUserLoggedIn.subscribe(value => this.isLoggedIn = value);
}

另见https://stackoverflow.com/a/35568924/217408

答案 1 :(得分:0)

有类似的需求,最终通过简单的getter来实现这一点-它将属性绑定到模板中(->传播更改)。更少的代码。

您可以直接设置全局变量,也可以在Globals类中实现设置器/获取器。

globals.ts

export class Globals{
    public static server_call_in_progress:boolean = true;
}

app.component.ts

import {Globals} from "./shared/globals";    
export class AppComponent{  
    constructor(){}
    ngOnInit(){}

    get server_call_in_progress(){
        return Globals.server_call_in_progress;
    }
}

app.component.html

<div *ngIf="server_call_in_progress">
    <div class="loader"></div>
</div>