Angular 有棱角的使用HostBinding装饰器手动更新属性
我有一个具有HostBind属性的组件,我想从其他组件手动更新该组件。我是这样写的:Angular 有棱角的使用HostBinding装饰器手动更新属性,angular,Angular,我有一个具有HostBind属性的组件,我想从其他组件手动更新该组件。我是这样写的: private\u选中:布尔值=false; @主机绑定('class.selected') 获取选定项():布尔值{ 返回此项。\u选中; } 设置选定项(值:布尔值){ 如果(选择此项===值){ 回来 } 该值为所选值; this.changeDetectorRef.markForCheck(); } 我有两个问题 首先。当我尝试更新ContentChild的属性时,不会应用更改。参见这里的示例-: 然
private\u选中:布尔值=false;
@主机绑定('class.selected')
获取选定项():布尔值{
返回此项。\u选中;
}
设置选定项(值:布尔值){
如果(选择此项===值){
回来
}
该值为所选值;
this.changeDetectorRef.markForCheck();
}
我有两个问题
首先。当我尝试更新ContentChild
的属性时,不会应用更改。参见这里的示例-:
然后UI将被更新,但我不明白为什么需要它
秒。当我尝试更新ViewChild
的属性时,会引发ExpressionChanged错误。例如-
又是为什么?通常,
markForCheck
调用可以防止错误。关于秒。引发错误的原因是-它在更改检测周期后运行,此处的任何更改都将触发错误(仅在开发模式下)。但也没有什么有趣的时刻
正如我使用的OnPush
strategymarkForCheck
实际上触发了错误,如果删除了对它的所有调用,则不会显示错误,也不会应用任何更改
另一件事是,markForCheck
显然不会触发新一轮的变化检测
所以,解决方案可能是在ngOnInit
hook中应用更改,因为它在更改检测之前运行,并且ViewChild
在那里可用。或者调用detectChanges
insetad ofmarkForChek
,因为它触发了新的更改检测周期
第一个一个。此案例与以前不同-现在有三个组件:应用程序、列表和项目。项目和列表在应用程序的模板中创建,然后项目投影到列表中
首先,列表的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();
}