簡體   English   中英

Angular 子組件不使用子路由更新導航欄

[英]Angular child component not update navbar with children routes

問題是,當我訂閱服務時,console.log 工作正常,但我無法更新導航欄中的用戶名,仍然是空白的。 你能幫我解決這個問題嗎?

我有這樣的路線:

const routes: Routes = [
  { path: 'login', component: LoginComponent },
  {
    path: '', component: NavComponent,canActivate: [AuthGuard],
    children: [
      { path: 'home', component: HomeComponent},
      { path: '**', component: PageNotFoundComponent }
    ]
  },
];

在 appcomponent.html 我添加了 router-outlet 以添加登錄組件

<router-outlet></router-outlet>

在我的 auth.service 我有:

(...)
  @Output() fireIsLoggedIn: EventEmitter<any> = new EventEmitter<any>(); 
(...)

  login(credentials: {email: string, password: string}): Observable<User> {
    return this.http
      .post<User>(`${this.url}/login`, credentials)
      .pipe(
        tap((user: User) => {
          if(user){
            localStorage.setItem('token', user.token);
            localStorage.setItem('user', JSON.stringify(user));
            this.router.navigate(['/home']);    
            this.fireIsLoggedIn.emit("for example user data")    
          }
        })
      )  
  }

  getEmitter() { 
    return this.fireIsLoggedIn; 
  } 

在我的 NavComponent.html 我有這個:

 <mat-sidenav-container class="sidenav-container">
  <mat-sidenav #drawer class="sidenav" fixedInViewport [attr.role]="(isHandset$ | async) ? 'dialog' : 'navigation'"
    [mode]="(isHandset$ | async) ? 'over' : 'side'" [opened]="(isHandset$ | async) === false">
    <!-- <mat-toolbar>Menu</mat-toolbar> -->
    <div fxLayout="column" fxLayoutAlign="space-between" style="height:100%;">
      <mat-nav-list>
        <a mat-list-item fxLayout="column" fxLayoutAlign="center center" [routerLinkActive]="'active'"
          routerLink="./page1">
          <div fxLayout="column" fxLayoutAlign="center center">
            <mat-icon class="mr-10">grid_view</mat-icon>
            <span>Page 1</span>
          </div>
        </a>
        <a mat-list-item fxLayout="column" fxLayoutAlign="center center" [routerLinkActive]="'active'"
          routerLink="./page2">
          <div fxLayout="column" fxLayoutAlign="center center">
            <mat-icon class="mr-10">grid_view</mat-icon>
            <span>Page 2</span>
          </div>
        </a>
        <a mat-list-item fxLayout="column" fxLayoutAlign="center center" [routerLinkActive]="'active'"
          routerLink="./page3">
          <div fxLayout="column" fxLayoutAlign="center center">
            <mat-icon class="mr-10">grid_view</mat-icon>
            <span>Page 3</span>
          </div>
        </a>
      </mat-nav-list>
      <mat-nav-list class="mb-16">
        <a mat-list-item fxLayout="column" fxLayoutAlign="center center" [routerLinkActive]="'active'"
          routerLink="./home">
          <div fxLayout="column" fxLayoutAlign="center center">
            <mat-icon class="mr-10">settings</mat-icon>
            <span>Settings</span>
          </div>
        </a>
        <a routerLink="./home">
          <div fxLayout="row" class="mt-8" fxLayoutAlign="center center"><img
              src="../../assets/images/logo.png" width="50"></div>
        </a>
      </mat-nav-list>
    </div>
  </mat-sidenav>
  <mat-sidenav-content>
    <mat-toolbar color="primary">
      <button type="button" aria-label="Toggle sidenav" mat-icon-button (click)="drawer.toggle()"
        *ngIf="isHandset$ | async">
        <mat-icon aria-label="Side nav toggle icon">menu</mat-icon>
      </button>
    
      <div style="position:absolute;right: 16px;left: 50%;transform: translateX(-50%);">
        <div fxLayout="row" fxLayoutAlign="center center">
          <img src="../../assets/images/logo.png" width="100">
        </div>
      </div>
      <button style="height: inherit;position: absolute;right:16px;" mat-button
        aria-label="Example icon-button with a heart icon" [matMenuTriggerFor]="menu"><img class="profile-avatar"
          src="https://www.flaticon.com/svg/static/icons/svg/149/149071.svg" alt="Photo of a Shiba Inu">
        <div class="profile-info profile-desktop">
          <div><span>{{username}}</span></div>
          <div><small>{{usertype}}</small></div>
        </div>

      </button>
      <mat-menu #menu="matMenu">
        <button mat-menu-item [routerLinkActive]="'active'" (click)="logout()">
          <mat-icon aria-hidden="false" aria-label="logout">logout</mat-icon>Logout
        </button>
      </mat-menu>
    </mat-toolbar>
    <!-- Add Content Here -->
    <router-outlet></router-outlet>
  </mat-sidenav-content>
</mat-sidenav-container>

在我的 NavComponent.ts 我有這個:

  constructor(private authService: AuthService) {}

  ngOnInit(){

    this.authService.getEmitter().subscribe((data) => { 
      console.log(data); //WORKS FINE
      this.username = data; // NOT UPDATE IN MY NAVBAR

  });


  }

非常感謝!

真的,我不太確定您是否可以使用 eventEmitter 和 Output 來獲得它,但我認為,在服務中您應該使用主題,而不是EventEmitter 和 @Output

fireIsLoggedIn: Subject<any> = new Subject<any>(); 

this.fireIsLoggedIn.next("for example user data") 

你可以直接訂閱

this.authService.fireIsLoggedIn.subscribe(res=>{...})

如上所述,您可能在 NavComponent 上設置了 ChangeDetectionStrategy.OnPush。 我想到了兩個解決方案:

  • 移除 NavComponent 上的 ChangeDetectionStrategy.OnPush
  • 將 ChangeDetectorRef 注入組件並調用detectChanges()方法:
  // code
  constructor(private authService: AuthService, 
              private changeDetectorRef: ChangeDetectorRef) {}

  ngOnInit(){

    this.authService.getEmitter().subscribe((data) => { 
      console.log(data); //WORKS FINE
      this.username = data; // NOT UPDATE IN MY NAVBAR
      this.changeDetectorRef.detectChanges();
    });
  }
  // code

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM