@ViewChild (CdkPortalOutlet) возвращает неопределенное значение в AfterViewInit - PullRequest
0 голосов
/ 05 января 2019

Попытка запросить ng-template с помощью CdkPortalOutlet всегда безуспешна, и я не могу понять, почему?

<ng-template CdkPortalOutlet></ng-template>

@ViewChild(CdkPortalOutlet) test: CdkPortalOutlet;

stackblitz

Ответы [ 2 ]

0 голосов
/ 27 июня 2019

Поскольку Angular 8 @ViewChild требует предоставления дополнительного параметра static, и в документации трудно найти, на какое значение его установить. Если установлено неправильно, это приведет к значению undefined при попытке получить CdkPortalOutlet с помощью @ViewChild.

TLDR

Установить @ViewChild(CdkPortalOutlet, { static: true }) при переходе на Angular 8.

Извлеченный комментарий из углового кода

Как выбрать значение флага static для использования: true или false?

Мы всегда рекомендуем получать результаты запроса в ngAfterContentInit для запросов контента. Это связано с тем, что к моменту запуска этой ловушки жизненного цикла обнаружение изменений для соответствующих узлов завершено, и мы можем гарантировать, что мы собрали все возможные результаты запроса.

По этой причине большинство приложений захотят использовать {static: false}. Этот параметр гарантирует, что в запросе будут найдены совпадения запроса, которые зависят от разрешения привязки (например, результаты внутри *ngIf с или *ngFor с). Если вам нужен доступ к TemplateRef в запросе для динамического создания представления, вы не сможете сделать это в ngAfterContentInit. Обнаружение изменений уже запущено в этом представлении, поэтому создание нового представления с шаблоном вызовет ошибку ExpressionHasChangedAfterChecked. В этом случае вам нужно установить флаг static на true и создать представление в ngOnInit. В большинстве других случаев рекомендуется использовать {static: false}.

Однако, чтобы упростить переход на версию 8, вы также можете установить флаг static на true, если код компонента уже зависит от результатов запроса, доступных за некоторое время до ngAfterContentInit. Например, если ваш компонент полагается на результаты запроса, заполняемые в хуке ngOnInit или в установщиках @Input, вам нужно будет либо установить флаг на true, либо заново обработать ваш компонент, чтобы приспособиться к более поздней синхронизации.

Примечание: Выбор статического параметра означает, что результаты запроса, вложенные в *ngIf или *ngFor, не будут найдены запросом. Эти результаты доступны только после запуска обнаружения изменений.

0 голосов
/ 05 января 2019

Чтобы использовать директиву CdkPortalOutlet в шаблоне AppComponent, необходимо импортировать PortalModule в AppModule (т. Е. NgModule, где был объявлен AppComponent)

import { PortalModule } from '@angular/cdk/portal';
...

@NgModule({
  imports:      [ BrowserModule, FormsModule, PortalModule, OverlayModule ],
                                              ^^^^^^^^^^^^
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})

export class AppModule { }

Также анализатор Angular HTML чувствителен к регистру, так что вам нужно использовать его как:

<ng-template cdkPortalOutlet></ng-template>
             ^^^
          lower case

Разветвленный стек-блиц

...