我试图从<mat-autocomplete ...>
export class ExampleComponent implements OnInit, AfterViewInit {
@ViewChildren('auto') matAutocomplete: QueryList<any>;
constructor(private cdr: ChangeDetectorRef) { }
ngAfterViewInit() {
this.foundItemsList.changes.subscribe(options => {
// ---> This simply works!
setTimeout(() => this.matAutocomplete.first._keyManager.setFirstItemActive(), 0);
// ---> This doesn't works?! No error shown, it just seems that the above function isn't called at all.
this.matAutocomplete.first._keyManager.setFirstItemActive()
this.cdr.detectChanges();
});
}
https://github.com/angular/material2/blob/master/src/lib/autocomplete/autocomplete.ts
AFAIK,detectChanges
做的是检查当前组件及其所有子组件的变化检测器,对吗?但它似乎并没有在上面的场景中发挥作用。
答案 0 :(得分:5)
this.cdr.detectChanges()
仅运行当前组件(和后代)的更改检测。如果setFirstItemActive()
导致其他地方发生变化,则不予承保。 setTimeout()
或zone.run(...)
或ApplicationRef.tick()
会导致对整个应用程序运行更改检测,因此不仅涵盖当前组件,还会涵盖每个绑定。
答案 1 :(得分:1)
请注意,如果您使用的是内容投影(ng-content
)或@HostBindings。
当您对承载内容的组件运行更改检测或设置主机绑定时,它实际上可能不会生效,因为它是“拥有”那些属性的父组件(甚至可能在不同的模块中)。 / p>
但是,与markForCheck()
相关的行为已于2017年5月更改,以标记以检查父组件中预计的ng-content
。 https://github.com/juleskremer/angular/commit/f894dbdd78cf463ed53b6c50d883326ff7fbff87
因此,detectChanges()
似乎不足以包含内容,您应该使用markForCheck
来触发包含内容的检查。