【发布时间】:2018-01-17 09:28:07
【问题描述】:
我有标签和标签组件:
tabs.component.ts:
@Component({
selector: 'cl-tabs',
template: `<ng-content></ng-content>`,
styleUrls: ['tabs.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TabsComponent implements AfterContentInit {
@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;
ngAfterContentInit(): void {
if (0 < this.tabs.length) {
this.activate(this.tabs.first);
}
}
activate(activatedTab: TabComponent) {
this.tabs.forEach(tab => tab.active = false);
activatedTab.active = true;
}
}
tab.component.ts:
@Component({
selector: 'cl-tab',
template: `<ng-content></ng-content>`,
styleUrls: ['tab.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TabComponent {
@Input() title: string;
@Input() @HostBinding('class.is-active') active: boolean = false;
}
app.component.html:
<cl-tabs>
<cl-tab *ngFor="let item of items" [title]="item.name">
<any-component [item]="item"></any-component>
</cl-tab>
</tabs>
当使用 *ngFor 创建选项卡时,会抛出 ExpressionChangedAfterItHasBeenCheckedError。
cdRef.detectChanges(),正如在许多情况下所建议的那样,没有帮助。
如果出现以下情况,错误就会消失:
- 标签是静态创建的;或
- HostBinding 已从“活动”字段中移除;或
- setTimeout 应用于 ngAfterContentInit。
为什么错误在前两种情况下消失了? 在这种特殊情况下,有没有比 setTimeout 更好的选择?
更新: 重现 plunker https://embed.plnkr.co/ZUOvf6NXCj2JOLTwbsYU/ 中的错误
【问题讨论】:
-
嘿,错误的确切措辞是什么?这是一个相当复杂的设置
-
@Maximus ERROR 错误:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改。以前的值:“假”。当前值:“真”。
-
我无法重现该问题。设置相当复杂。如果您设置一个具有可重现问题的 plunker,我会看看
-
@Maximus 更新了问题,其中包含指向错误的 plunker 的链接。
-
标签是静态创建的 - 静态是什么意思?
标签: javascript angular exception