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