如何让父组件在Angular 2中有效地监听子组件所做的更改?

时间:2017-05-21 14:12:11

标签: angular menu components angular2-routing logout

这主要是设计/方法问题。

我想达到的目标:

=>用户注销时隐藏注销链接。仅在用户登录时才显示注销链接。

问题:

菜单和注销是两个不同的组件。因此,当用户点击注销时,将此信息传递给菜单组件证明是非常困难的。我正在寻找一种更恰当/直接的方法。请给我建议 我的代码片段如下 -

menu.component.html

<div id="navbar" class="collapse navbar-collapse">
  <ul class="nav navbar-nav">
    <li routerLinkActive="active"> <a [routerLink]="[ '/home' ]" routerLinkActive="active">Home</a></li>
    <li routerLinkActive="active" *ngIf="loggedIn">
      <app-logout (onLogOutClick)="onLogOutClick($event)"></app-logout>
    </li>
  </ul>
</div>

menu.component.ts

import { SharedService } from '../shared.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-menu',
  templateUrl: './menu.component.html',
  styleUrls: ['./menu.component.css'],
  providers: [SharedService]
})
export class MenuComponent implements OnInit {

  loggedIn: boolean = false;
  constructor(private sharedService: SharedService) { }

  ngOnInit() {
    this.loggedIn = this.sharedService.isLoggedIn();
  }

  onLogOutClick($event) {
    this.loggedIn = false;
  }
}

logout.component.html

<a [routerLink]="[ '/logout' ]" routerLinkActive="active" (click)="onClick()">Logout</a>

logout.component.ts

   import { Router } from '@angular/router';
import { Component, EventEmitter, OnInit, Output, ViewChild } from '@angular/core';
import { SharedService } from '../shared.service';
import { ModalComponent } from '../modal.component';

@Component({
  selector: 'app-logout',
  templateUrl: './logout.component.html',
  styleUrls: ['./logout.component.css'],
  providers: [SharedService]
})
export class LogoutComponent implements OnInit {

  @Output() onLogOutClick = new EventEmitter<boolean>();

  constructor(private sharedService: SharedService, private router: Router) { }

  ngOnInit() {

  }

  onClick() {
    console.log('logout component : onclick clicked..');

    if (this.sharedService.isLoggedIn) {
      this.sharedService.logout();
      this.onLogOutClick.emit(true);

    } else {
      // shouldn't reach
      console.log('User not logged in. Discarding logout attempt');
    }
    this.routeToLoginPage();

  }

  routeToLoginPage() {
    this.router.navigate(['/login']);
  }

}

1 个答案:

答案 0 :(得分:0)

SharedService中定义Observable您可以访问以确定用户是否已登录。

@Injectable()
export class SharedService {

    isLoggedIn$: BehaviorSubject<boolean> = new BehaviorSubject(false)

    login(): void {
        // login business logic
        this.isLoggedIn$.next(true)
    }

    logout(): void {
        // logout business logic
        this.isLoggedIn$.next(false)
    }
}

让任何组件订阅isLoggedIn$州。 E.g:

export class ButtonComponent implements OnInit, OnDestroy {

    isLoggedIn: boolean

    // reference to the isLoggedIn$ subscription, see ngOnDestroy
    private _sub: Subscription

    constructor(private ss: SharedService) {}

    ngOnInit(): void {
        this._sub = this.ss.isLoggedIn$.subscribe(loginState => isLoggedIn = loginState)
    }

    // Unsubscribe from login state on destroy to prevent memory leak
    ngOnDestroy(): void {
        this._sub.unsubscribe()
    }
}