Angular 有棱角的使用HostBinding装饰器手动更新属性

Angular 有棱角的使用HostBinding装饰器手动更新属性,angular,Angular,我有一个具有HostBind属性的组件,我想从其他组件手动更新该组件。我是这样写的: private\u选中:布尔值=false; @主机绑定('class.selected') 获取选定项():布尔值{ 返回此项。\u选中; } 设置选定项(值:布尔值){ 如果(选择此项===值){ 回来 } 该值为所选值; this.changeDetectorRef.markForCheck(); } 我有两个问题 首先。当我尝试更新ContentChild的属性时,不会应用更改。参见这里的示例-: 然

我有一个具有HostBind属性的组件,我想从其他组件手动更新该组件。我是这样写的:

private\u选中:布尔值=false;
@主机绑定('class.selected')
获取选定项():布尔值{
返回此项。\u选中;
}
设置选定项(值:布尔值){
如果(选择此项===值){
回来
}
该值为所选值;
this.changeDetectorRef.markForCheck();
}
我有两个问题

首先。当我尝试更新
ContentChild
的属性时,不会应用更改。参见这里的示例-:

然后UI将被更新,但我不明白为什么需要它

。当我尝试更新
ViewChild
的属性时,会引发ExpressionChanged错误。例如-


又是为什么?通常,
markForCheck
调用可以防止错误。

关于。引发错误的原因是-它在更改检测周期后运行,此处的任何更改都将触发错误(仅在开发模式下)。但也没有什么有趣的时刻

正如我使用的
OnPush
strategy
markForCheck
实际上触发了错误,如果删除了对它的所有调用,则不会显示错误,也不会应用任何更改

另一件事是,
markForCheck
显然不会触发新一轮的变化检测

所以,解决方案可能是在
ngOnInit
hook中应用更改,因为它在更改检测之前运行,并且
ViewChild
在那里可用。或者调用
detectChanges
insetad of
markForChek
,因为它触发了新的更改检测周期

第一个一个。此案例与以前不同-现在有三个组件:应用程序、列表和项目。项目和列表在应用程序的模板中创建,然后项目投影到列表中

首先,列表的
ngAfterViewInit
内部的
detectChanges
不会更新项,可能是因为项不是列表的直接子项或父项。此外,在应用程序的
ngAfterViewInit
中调用
markForCheck
时,如果不调用
markForCheck
,则调用
markForCheck
不会触发错误(如second案例)

正确的方法是在列表的
ngAfterContentInit
中应用更改。此挂钩在更改检测之前运行,所有内容都将正确呈现到dom中


您是否有义务在组件标签上直接添加所选的类
?或者我可以提出一个解决方案来解决问题?事实上,我想了解什么是错的,或者为什么它会这样工作,而不仅仅是如何避免错误。
@ContentChildren(ItemComponent) items: QueryList<ItemComponent>;

...

ngAfterViewInit() {
  this.updateItems();
  this.items.changes.subscribe(() => {
    this.updateItems();
  });

  this.changeDetectorRef.markForCheck();
}
private updateItems() {
  this.items.forEach(item => {
    item.selected = this.selected === item.value;
  });
}
setTimeout(() => {
  this.changeDetectorRef.markForCheck();
});
@ViewChild(ItemComponent) item: ItemComponent;

...

ngAfterViewInit() {
  this.item.selected = true;
  this.changeDetectorRef.markForCheck();
}