Я пытаюсь автоматически выбрать первое значение из набора параметров в <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 проверяет детектор изменений текущего компонента и всех его дочерних компонентов, правильно? Но похоже, что в приведенном выше сценарии это не работает.

7
kav 2 Янв 2018 в 17:01

2 ответа

Лучший ответ

this.cdr.detectChanges() запускает обнаружение изменений только для текущего компонента (и потомков). Если setFirstItemActive() вызывает изменения где-либо еще, это не рассматривается. setTimeout() или zone.run(...) или ApplicationRef.tick() запускают обнаружение изменений для всего приложения и, следовательно, охватываются все привязки, а не только текущий компонент.

6
Günter Zöchbauer 2 Янв 2018 в 14:06

Будьте осторожны, если вы используете проекцию контента (ng-content) или @HostBindings.

Когда вы запускаете обнаружение изменений для компонента, на котором размещен контент, или устанавливаете привязку хоста, это может не вступить в силу, потому что это родительский компонент (который может быть даже в другом модуле), который «владеет» этими атрибутами.

Однако поведение, связанное с markForCheck(), было изменено в мае 2017 г., чтобы пометить для проверки проецируемый ng-content в родительском компоненте. https://github.com/juleskremer/angular/commit/f894c650bdddddd

Таким образом, кажется, что detectChanges() недостаточно для включенного контента, и вы должны использовать вместо него markForCheck, который запустит проверку включенного контента.

2
Simon_Weaver 21 Авг 2018 в 10:13