Javascript 如何在angular和#x27之间共享数据;s服务和组件?
如何以实时方式在服务和组件之间绑定数据 让我们假设Javascript 如何在angular和#x27之间共享数据;s服务和组件?,javascript,angular,typescript,ionic-framework,data-binding,Javascript,Angular,Typescript,Ionic Framework,Data Binding,如何以实时方式在服务和组件之间绑定数据 让我们假设isAuthenticated验证服务的公共变量影响组件中的某些视图。我的问题是如何订阅isAuthenticated变量 服务: import { Injectable } from '@angular/core'; @Injectable() export class Authentication { isAuthenticated:boolean = false; login() { localStorage.setI
isAuthenticated
验证服务的公共变量影响组件中的某些视图。我的问题是如何订阅isAuthenticated
变量
服务:
import { Injectable } from '@angular/core';
@Injectable()
export class Authentication {
isAuthenticated:boolean = false;
login() {
localStorage.setItem('access_token', 'true');
this.isAuthenticated = true;
}
}
组成部分:
...
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private isAuthenticated:boolean = false;
constructor(public authService: Authentication) {
this.isAuthenticated = this.authService.isAuthenticated'
}
}
home.html
...
<div *ngIf="isAuthenticated">Authentication view</div>
<div *ngIf="!isAuthenticated">Unauthentication view</div>
...
。。。
身份验证视图
未验证视图
...
根据上面的当前流程,绑定工作正常,但不是实时的
那么,最好的方法是什么:
1-在身份验证服务内创建一个可观察的,以便在组件内订阅它
2-使用以下方式进行绑定:
...
<div *ngIf="authService.isAuthenticated">Authentication view</div>
<div *ngIf="!authService.isAuthenticated">Unauthentication view</div>
...
。。。
身份验证视图
未验证视图
...
第二种方法很有效,但我不知道它是否是最佳实践
谢谢。我从你的标签上猜你在使用离子框架?这可以通过事件来实现吗
// first page (publish an event when a user is created)
constructor(public events: Events) {}
createUser(user) {
console.log('User created!')
this.events.publish('user:created', user, Date.now());
}
// second page (listen for the user created event after function is called)
constructor(public events: Events) {
events.subscribe('user:created', (user, time) => {
// user and time are the same arguments passed in `events.publish(user, time)`
console.log('Welcome', user, 'at', time);
});
}
示例代码取自:我建议使用
BehaviorSubject
。它是一个可观察的
,因此您可以订阅它,但您也可以通过调用行为subject.next(newValue)
来控制它何时发出新值。创建BehaviorSubject时,必须向其传递初始值。在您的情况下,它是false
@Injectable()
export class Authentication {
isAuthenticated = new BehaviorSubject<boolean>(false);
login() {
localStorage.setItem('access_token', 'true');
this.isAuthenticated.next(true);
}
}
也可以使用异步管道在html中订阅
export class HomePage {
private isAuthenticated: BehaviorSubject<boolean>;
constructor(public authService: Authentication) {
this.isAuthenticated = this.authService.isAuthenticated;
}
}
导出类主页{
私人身份验证:行为主体;
构造函数(公共身份验证服务:身份验证){
this.isAuthenticated=this.authService.isAuthenticated;
}
}
-
身份验证视图
未验证视图
与常规Observable不同,当您在BehaviorSubject上调用subscribe时,您作为参数传递给subscribe的函数将立即执行。这是因为BehaviorSubject总是有一个值。您可以使用
this.authService.isAuthenticated.value访问它,但它在这里不是很有用。使用RXJS。使用行为主题,您可以在注入服务并具有初始状态的多个组件中推送状态并订阅状态更改。定义行为主体时,还必须定义一个起始值,此处为false。您所要做的就是调用Behavior Subject to push状态的。下一步(true)
,如下所示:
...
@Injectable()
export class Authentication {
private _isAuthenticated: BehaviourSubject<boolean> = new BehaviourSubject(false);
public get isAuthenticated(): Observable<boolean> {
return this._isAuthenticated.asObservable();
}
login() {
localStorage.setItem('access_token', 'true');
this._isAuthenticated.next(true);
}
}
目前我正在使用此解决方案:
import { DoCheck } from '@angular/core';
//...
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private isAuthenticated:boolean = false;
constructor(public authService: Authentication) { }
ngDoCheck() {
if (this.authService.isAuthenticated)) {
//..if authenticated do this
} else {
//..if not do this
}
}
}
即使我不确定这是一种好方法。也不要在构造函数中执行来自的请求(即调用您的服务检查是否已验证)。在组件上实现OnInit
,然后在组件上执行。可以在提供程序(服务)中创建事件?应该可以,但我不确定这是否是最佳做法,什么叫“登录”方法?可以更改它,使其返回一个可观察的或承诺,然后从该调用中返回离子事件(假设调用它的内容与您调用“登录”的页面不在同一页上,在这种情况下,事件将不必要)。我不认为您可以更改事件值,如…next(false)或者类似的东西如何导入BehaviorSubject?您使用的是哪个版本的RxJS?对于RxJS v6+您可以像这样从“RxJS”导入它import{BehaviorSubject}代码>
...
@Injectable()
export class Authentication {
private _isAuthenticated: BehaviourSubject<boolean> = new BehaviourSubject(false);
public get isAuthenticated(): Observable<boolean> {
return this._isAuthenticated.asObservable();
}
login() {
localStorage.setItem('access_token', 'true');
this._isAuthenticated.next(true);
}
}
...
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage implements OnInit {
private isAuthenticated:boolean = false;
private readonly _authService: Authentication;
constructor(authService: Authentication) {
this._authService = authService;
}
public ngOnInit(): void {
this._authService.isAuthenticated
.subscribe((isAuthenticated) => this.isAuthenticated = isAuthenticated)
}
}
import { DoCheck } from '@angular/core';
//...
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
private isAuthenticated:boolean = false;
constructor(public authService: Authentication) { }
ngDoCheck() {
if (this.authService.isAuthenticated)) {
//..if authenticated do this
} else {
//..if not do this
}
}
}