状态更改后,Angular 组件未更新

问题描述 投票:0回答:1

我来自 React,到目前为止我很喜欢 Angular 18。然而,我正在努力尝试理解组件如何以角度方式工作,特别是从子组件更新 DOM。

我有一个父组件,它有 2 个子组件,一个是角度组件,另一个只是一个 div。理论上两者应该做同样的事情。我想要做的是从某些视图中“制表符”。因此,我可以从父组件切换到任一视图。我使用一个简单的函数 goBack 函数来更改 currentTab 变量来完成此操作。这在常规 div 元素中工作得很好,但在角度组件中,当我传递输入(并记录父组件的结果)时,它显示变量或状态已更改,但视图未更改。为了渲染不同的视图,我使用 *ngIf。我注意到角度组件的类似问题没有按预期运行,我想知道为什么。

这里有一个小片段,可以帮助进一步阐述我的问题。

父组件.html


<div class="container"> <div \*ngIf="currentTab === 'chose-options'" class="button-container"> <button (click)="choseGameOption('new-game')" value="new-game" type="button" class="button" > <p>New Game</p> </button> <button (click)="choseGameOption('saved-game')" value="saved-game" type="button" class="button" > Saved Game </button> </div>

<div \*ngIf="currentTab === 'new-game'"> <app-jeopardy-game-board \[goBack\]="goBack"></app-jeopardy-game-board> <button (click)="goBack()">go back</button> </div>

<div \*ngIf="currentTab === 'saved-game'"> <p>Choose saved game</p> <button (click)="goBack()">back</button> </div> </div>

父组件.ts

export class JeopardyComponent {
  @ViewChild(AddJeopardyQuestionComponent)
  dialog!: AddJeopardyQuestionComponent;
  currentTab: string = 'chose-options';
  private cd: ChangeDetectorRef = inject(ChangeDetectorRef);

  choseGameOption(gameOption: string) {
    this.currentTab = gameOption;
    this.cd.detectChanges();
  }
  goBack() {
    this.currentTab = 'chose-options';
    console.log(this.currentTab);
  }
}

子组件.html:


// ... misc. table data (no other logic)

<button (click)="onBackClick()">
        <mat-icon>keyboard_arrow_left</mat-icon>
      </button>

子组件.ts


import { CommonModule } from '@angular/common';
import { Component, Input, Output } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';


@Component({
  selector: 'app-jeopardy-game-board',
  standalone: true,
  imports: [MatIconModule, CommonModule],
  templateUrl: './jeopardy-game-board.component.html',
  styleUrl: './jeopardy-game-board.component.scss',
})
export class JeopardyGameBoardComponent {
  @Input() goBack!: () => void;

  // @Output() viewEvent: EventEmitter = new EventEmitter();

  onBackClick() {
    this.goBack();
    // this.viewEvent.emit();
  }
}

我尝试过使用 ChangeDetectorRef、ViewChild()、输出 EventEmmiters,似乎没有像常规 div 元素那样更新 UI 抱歉,如果我的术语有问题,我对 Angular 还很陌生

javascript angular typescript components
1个回答
0
投票

我认为你正在以相反的方式做这件事。 您的子组件应该通过输出发出一个事件,表明其返回按钮已被单击以通知其父组件。 然后父级应该对这个发出的事件做出反应来完成它的事情。

子组件 ts

import { CommonModule } from '@angular/common';
import { Component, Input, Output } from '@angular/core';
import { MatIconModule } from '@angular/material/icon';


@Component({
  selector: 'app-jeopardy-game-board',
  standalone: true,
  imports: [MatIconModule, CommonModule],
  templateUrl: './jeopardy-game-board.component.html',
  styleUrl: './jeopardy-game-board.component.scss',
})
export class JeopardyGameBoardComponent {
  @Output() backClick: EventEmitter = new EventEmitter();

  onBackClick() {
    this.backClick.emit();
  }
}

子组件 html:

<button (click)="onBackClick()">
   <mat-icon>keyboard_arrow_left</mat-icon>
</button>

父组件ts

export class JeopardyComponent {
  // other stuff

  goBack() {
    this.currentTab = 'chose-options';
    console.log(this.currentTab);
  }
}

父组件html

<div *ngIf="currentTab === 'new-game'"> 
  <app-jeopardy-game-board (backClick)="goBack()"/> 
</div>

<div *ngIf="currentTab === 'saved-game'"> 
  <p>Choose saved game</p> 
  <button (click)="goBack()">back</button>
</div>
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.