在我的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类型
答案 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);
}
答案 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>