【问题标题】:Angular 2: have component auto detect variable change in a serviceAngular 2:让组件自动检测服务中的变量变化
【发布时间】:2018-06-14 08:19:00
【问题描述】:

我目前面临的问题是,在功能上,当用户登录时,我的导航栏不会自动更新以向他们显示正确的链接。只有当我手动刷新不需要的页面时它才会更新,因为这是一个单页应用程序。我可以处理注销 OK,因为注销按钮和功能位于控制导航栏的组件内。但是,登录是通过身份验证服务控制的,并且对我的组件不可见。我尝试将 isLoggedIn 布尔值设为公共,然后将组件导入身份验证服务并在登录时将值设置为 true,但这会产生非描述 zone.js 错误。请参阅下文 - 感谢所有帮助。

app.component 控制我的导航栏:

export class AppComponent implements OnInit{
    private isLoggedIn: boolean;

    constructor(private router: Router, private authenticationService: AuthenticationService) { }

    ngOnInit() {
        this.isLoggedIn = this.authenticationService.isLoggedIn();
    }

    logout() {
        this.isLoggedIn = false;
        this.authenticationService.logout();
        this.router.navigate([""]);
    }

    title = 'MYlestone';
}

app.component 模板:

<div class="site-container">
    <nav class="navbar navbar-toggleable-md">
        <div *ngIf="isLoggedIn">
            <span class="navbar-brand text-color">MYlestone</span>
        </div>
        <div *ngIf="!isLoggedIn">
            <span class="navbar-brand text-color" [routerLink]="['']" style="cursor:pointer">MYlestone</span>
        </div>
        <div>
            <div class="navbar-nav" *ngIf="isLoggedIn">
                <a class="nav-item nav-link" href="#" [routerLink]="['content']">My Content</a>
                <a class="nav-item nav-link" href="#" [routerLink]="['about']">About</a>
                <div class="ml-auto">
                    <a class="nav-item nav-link" href="#" (click)="logout()">Logout</a>
                </div>
            </div>
        </div>
    </nav>
    <div class="container-fluid text-color">
        <!-- let client side routing take over, see app.routing.ts -->
        <router-outlet></router-outlet>
    </div>
</div>

如您所见,isLoggedIn 已在 ngOnInit 方法中[正确] 设置,并且我的组件在单击注销按钮时会相应更新。我正在努力弄清楚的是如何在用户登录时更新此组件中的isLoggedIn 布尔值,这发生在执行此组件的 ngOnInit 方法之后。以防万一需要/需要,您可以在下面找到负责实际登录用户的 authentication.service:

@Injectable()
export class AuthenticationService {
    constructor(private http: Http) { }

    login(email: string, password: string) {
        return this.http.post('http://localhost:36000/api/accounts/authenticate', { email: email, password: password })
            .map((response: Response) => {
                let user = response.json();
                if (user && user.token) {
                    localStorage.setItem('currentUser', JSON.stringify(user));
                }
            });
    }

    logout() {
        localStorage.removeItem('currentUser');
    }

    isLoggedIn() {
        //check to see if token exists
        if (localStorage.getItem('currentUser')) {
            return true;
        }
        else {
            return false;
        }
    }
}

【问题讨论】:

    标签: angular typescript authentication


    【解决方案1】:

    在您的组件类中,您可以将isLoggedIn 设为从服务获取当前值的属性。 Angular 的变更检测机制会在适当的时候访问它并更新呈现的 HTML。

    public get isLoggedIn(): boolean {
        return this.authenticationService.isLoggedIn();
    }
    

    【讨论】:

      【解决方案2】:

      您应该将isLoggedIn() 的定义从函数移动到组件可以订阅的 Observable 中,并在需要时进行更新。这只是一种可能的解决方案,有很多方法可以解决这个问题。

      Service.ts

      private isLoggedIn$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
      
      // Sets up the isLoggedIn Observable
      getLoggedInStatus(): Observable<boolean> {
          return this.isLoggedIn$.asObservable();
      }
      
      // Updates the Behavior Subject
      updateLoggedInStatus(LoggedIn: boolean): void {
          this.isLoggedIn$.next(LoggedIn);
      }
      

      Component.ts

      constructor(
          private _Service: Service
      )
      
      ngOnInit() {
          this._Service.getLoggedInStatus().subscribe(_isLoggedIn => {
              this.isLoggedIn = _isLoggedIn;
          }
      }
      

      【讨论】:

      • 我出于好奇也对此进行了测试,它确实有效。赞成你的时间和不同的观点。我确实更喜欢 @ConnorsFan 的解决方案,因为它简单易懂
      猜你喜欢
      • 2018-09-06
      • 2017-06-07
      • 2017-06-04
      • 1970-01-01
      • 2016-07-15
      • 2019-06-09
      • 2017-01-01
      • 2018-07-10
      • 2018-05-14
      相关资源
      最近更新 更多