Как мне использовать новую статическую опцию для @ViewChild в Angular 8?
Как настроить новый дочерний элемент Angular 8?
@ViewChild('searchText', {read: ElementRef, static: false})
public searchTextInput: ElementRef;
против
@ViewChild('searchText', {read: ElementRef, static: true})
public searchTextInput: ElementRef;
Что лучше? Когда я должен использовать static:true
против static:false
?
Ответы
Ответ 1
В большинстве случаев вы захотите использовать {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
.
Вы можете использовать команду ng update
углового клина для автоматического обновления текущей базы кода.
Для руководства по миграции и даже больше информации об этом вы можете проверить здесь
Ответ 2
Из угловых документов
статический - разрешать или не разрешать результаты запроса перед выполнением обнаружения изменений (т.е. возвращать только статические результаты). Если эта опция не указана, компилятор вернется к своему поведению по умолчанию, которое будет использовать результаты запроса для определения времени разрешения запроса. Если какие-либо результаты запроса находятся во вложенном представлении (например, * ngIf), запрос будет разрешен после выполнения обнаружения изменений. В противном случае оно будет разрешено до запуска обнаружения изменений.
Может быть, лучше использовать static:true
если ребенок не зависит ни от каких условий. Если видимость элемента изменяется, то static:false
может дать лучшие результаты.
PS: Поскольку это новая функция, нам может потребоваться запустить тесты производительности.
редактировать
Как упомянул @Massimiliano Sartoretto, коммит github может дать вам больше идей.
Ответ 3
Пришел сюда, потому что 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 для неопубликованных ссылок. Имхо, этот конкретный случай должен упоминаться как нулевое исключение, вероятно, будет первым способом, с которым вы столкнетесь с этой особенностью, как это было для меня.
Ответ 4
Так что, как правило, вы можете пойти на следующее:
-
{ static: true }
должен быть установлен, когда вы хотите получить доступ к ViewChild
в ngOnInit
.
-
{ static: false }
может быть доступно только в ngAfterViewInit
. Это также то, к чему вы хотите *ngIf
когда у вас есть структурная директива (то есть *ngIf
).