Как мне использовать новую статическую опцию для @ViewChild в Angular 8? - PullRequest
51 голосов
/ 29 мая 2019

Как настроить новый дочерний элемент Angular 8?

@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;

против

@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;

Что лучше?Когда я должен использовать static:true против static:false?

Ответы [ 4 ]

55 голосов
/ 29 мая 2019

В большинстве случаев вы захотите использовать {static: false}. Установка этого параметра гарантирует, что будут найдены совпадения запросов, которые зависят от разрешения привязки (например, структурные директивы *ngIf, etc...).

Пример использования static: false:

@Component({
  template: `
    <div *ngIf="showMe" #viewMe>Am I here?</div>
    <button (click)="showMe = !showMe"></button>
  ` 
})
export class ExampleComponent {
  @ViewChild('viewMe', { static: false })
  viewMe?: ElementRef<HTMLElement>; 

  showMe = false;
}

static: false будет стандартным вариантом отката в Angular 9. Подробнее здесь и здесь

Опция { static: true } была введена для поддержки создания встроенных представлений на лету. Когда вы динамически создаете представление и хотите получить доступ к TemplateRef, вы не сможете сделать это в ngAfterViewInit, так как это приведет к ошибке ExpressionHasChangedAfterChecked. Установка статического флага в true создаст ваше представление в ngOnInit.

Тем не менее:

В большинстве других случаев рекомендуется использовать {static: false}.

Имейте в виду, что опция { static: false } будет установлена ​​по умолчанию в Angular 9. Это означает, что установка статического флага больше не требуется, если вы не хотите использовать опцию static: true.

Вы можете использовать команду angular cli ng update для автоматического обновления вашей текущей кодовой базы.

Для руководства по миграции и даже дополнительной информации об этом вы можете проверить здесь

10 голосов
/ 29 мая 2019

Из угловых Документы

статический - разрешать или не разрешать результаты запроса перед выполнением обнаружения изменений (т.е. возвращать только статические результаты). Если эта опция не указана, компилятор вернется к своему поведению по умолчанию, которое будет использовать результаты запроса для определения времени разрешения запроса. Если какие-либо результаты запроса находятся во вложенном представлении (например, * ngIf), запрос будет разрешен после выполнения обнаружения изменений. В противном случае оно будет разрешено до запуска обнаружения изменений.

Может быть, лучше использовать static:true, если ребенок не зависит ни от каких условий. Если видимость элемента изменится, static:false может дать лучшие результаты.

PS: Поскольку это новая функция, нам может потребоваться запустить тесты производительности.

Редактировать

Как упомянул @Massimiliano Sartoretto, коммит github может дать вам больше идей.

1 голос
/ 18 июля 2019

Таким образом, как правило, вы можете перейти к следующему:

  • { static: true } необходимо установить, когда вы хотите получить доступ к ViewChild в ngOnInit.

  • { static: false } доступен только в ngAfterViewInit.Это также то, к чему вы хотите стремиться, когда у вас есть структурная директива (например, *ngIf) для вашего элемента в шаблоне.

1 голос
/ 10 июля 2019

Пришел сюда, потому что ViewChild был нулевым в ngOnInit после обновления до Angular 8.

Статические запросы заполняются до ngOnInit, тогда как динамические запросы (статические: ложные) выполняются после. Другими словами, если viewchild теперь является нулевым в ngOnInit после того, как вы установили static: false, вы должны рассмотреть возможность изменения на static: true или переместить код в ngAfterViewInit.

См. https://github.com/angular/angular/blob/master/packages/core/src/view/view.ts#L332-L336

Другие ответы верны и объясняют, почему это так: запросы зависят от структурных директив, например, ссылка ViewChild внутри ngIf должна запускаться после разрешения условия этой директивы, то есть после обнаружения изменения. Однако можно смело использовать static: true и, таким образом, разрешать запросы перед ngOnInit для неопубликованных ссылок. В данном конкретном случае упоминание в качестве нулевого исключения, вероятно, может быть первым способом, с которым вы столкнетесь с этой особенностью, как и для меня.

...