6

我在使用登录时不刷新的组件时遇到问题。

该组件是 navbar.component ,其中包含指向我的页面/组件的链接。在它上面,有一个“登录”链接呈现 login.component,我可以在上面提供用户名和密码,然后单击登录按钮。login.component 使用 user.service,它使用 login.component 提供的用户名和密码调用后端,存储接收到的令牌并重定向到'/'。

此时,应该隐藏 navbar.component 上的“登录”链接并显示“注销”链接,但是在我单击导航栏上的其他链接之一之前什么都没有发生。

2个链接如下:

<a [hidden]="userService.isLoggedIn" [routerLink]="['Login']">Login</a>
<a [hidden]="!userService.isLoggedIn" (click)="userService.logout();" href="javascript:void(0)">Logout</a>

我了解存储令牌并从 user.service 重定向不会触发更改检测,并且我的属性 userService.isLoggedIn 不是可观察的,所以我知道我遗漏了一些东西,但不确定该方法是/应该是什么.

我尝试注入 ApplicationRef 来调用 tick() 方法,希望这会触发更改检测,但失败了。

我应该让我的财产 userService.isLoggedIn 成为可观察的吗?

4

2 回答 2

7
export class UserService {
  isLoggedIn:BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
}
@Component({
...
template: `
<a [hidden]="userService.isLoggedIn | async" [routerLink]="['Login']">Login</a>
<a [hidden]="!(userService.isLoggedIn | async)" (click)="userService.logout();" href="javascript:void(0)">Logout</a>
`
})
export class MyComponent {
  constructor(private userService: UserService) {}
}
于 2016-05-04T10:26:48.023 回答
3

我了解存储令牌并从 user.service 重定向不会触发更改检测

没错,但是如果您使用的是 Angular Http 服务,当从服务返回数据时,更改检测应该在您的回调函数/方法执行后运行。您的导航栏组件是否使用OnPush更改检测策略?(如果是这样,那将解释为什么不更新。)

Günter 的回答是有效的,因为异步管道不仅会自动subscribe()s 到可观察对象,而且还会markForCheck()在可观察对象发出新值时调用。这确保了组件(及其所有祖先)将被检测到更改,即使其中任何一个正在使用OnPush.


仍然使用 BehaviorSubject 的另一种方法,它更命令式(而不是声明式),如下所示:

  • 将 ChangeDetectorRef 注入您的导航栏组件
  • subscribe()到服务可观察
  • 当 observable 触发时,调用detectChanges(). 这将检查组件及其子组件(如果有的话)。这可能比 using 更有效markForCheck(),尤其是在 NavBar 没有任何子项的情况下。但是考虑到登录/注销可能是罕见的事件,效率可能并不重要。但是,我更喜欢detectChanges()仅在更改视图/组件状态时使用(就像这里的情况,基于我在下面的实现方式)而不是应用程序状态 - 即影响多个组件的东西,因此markForCheck()会更合适.
@Component({
  ...
  template: `
    <a [hidden]="userIsLoggedIn" [routerLink]="['Login']">Login</a>
    <a [hidden]="!userILoggedIn" (click)="userService.logout()">Logout</a>
  `
})
export class NavBar {
  userIsLoggedIn = false;
  constructor(private userService: UserService, private _ref: ChangeDetectorRef) {}
  ngOnInit() {
     this.userService.isLoggedIn.subscribe( userIsLoggedIn => {
        this.userIsLoggedIn = userIsLoggedIn;
        this._ref.detectChanges();
     });
  }
}
于 2016-05-09T17:06:32.400 回答