为什么在组件内部调用 detectChanges() 不会更新值,但在 setTimeout() 中包装代码会更新值?
Why calling detectChanges() inside component doesn't update values, but wrapping code in setTimeout() does it?
我正在尝试自动 select <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
所做的是检查当前组件及其所有子组件的变化检测器,对吗?但是上面的场景好像不行。
this.cdr.detectChanges()
仅 运行 对当前组件(和后代)进行更改检测。如果 setFirstItemActive()
导致其他地方发生变化,则不包括在内。 setTimeout()
或 zone.run(...)
或 ApplicationRef.tick()
导致整个应用程序的更改检测为 运行,因此每个绑定都被覆盖,而不仅仅是当前组件。
请注意您使用的是内容投影 (ng-content
) 还是@HostBindings。
当您 运行 更改托管内容的组件的检测或设置主机绑定时,它实际上可能不会生效,因为它是父组件(甚至可能位于不同的模块中)'owns'那些属性。
但是,与 markForCheck()
相关的行为已于 2017 年 5 月更改为标记以检查父组件中投影的 ng-content
。 https://github.com/juleskremer/angular/commit/f894dbdd78cf463ed53b6c50d883326ff7fbff87
因此,detectChanges()
似乎不足以包含内容,您应该使用 markForCheck
来代替,这将触发对包含内容的检查。
我正在尝试自动 select <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
所做的是检查当前组件及其所有子组件的变化检测器,对吗?但是上面的场景好像不行。
this.cdr.detectChanges()
仅 运行 对当前组件(和后代)进行更改检测。如果 setFirstItemActive()
导致其他地方发生变化,则不包括在内。 setTimeout()
或 zone.run(...)
或 ApplicationRef.tick()
导致整个应用程序的更改检测为 运行,因此每个绑定都被覆盖,而不仅仅是当前组件。
请注意您使用的是内容投影 (ng-content
) 还是@HostBindings。
当您 运行 更改托管内容的组件的检测或设置主机绑定时,它实际上可能不会生效,因为它是父组件(甚至可能位于不同的模块中)'owns'那些属性。
但是,与 markForCheck()
相关的行为已于 2017 年 5 月更改为标记以检查父组件中投影的 ng-content
。 https://github.com/juleskremer/angular/commit/f894dbdd78cf463ed53b6c50d883326ff7fbff87
因此,detectChanges()
似乎不足以包含内容,您应该使用 markForCheck
来代替,这将触发对包含内容的检查。