Есть ли ловушка жизненного цикла, которая запускается один раз после инициализации компонентов, но также и после загрузки двустороннего связывания? - PullRequest
0 голосов
/ 22 июня 2019

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

Большинство перехватов выполняется до загрузки входного текста с помощью двусторонней привязки. Другие также запускаются каждый раз, когда кто-то выбирает другое поле.

Код: https://stackblitz.com/edit/angular-pxrssq

import { Component, OnInit, Input, ViewChild } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    <input #input type="text" [(ngModel)]="info.one"/>
    <input type="text" [(ngModel)]="info.two"/>`,
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  @Input() info;
  @ViewChild('input', {static: true} ) input;

  constructor() { }

  ngOnInit() {
    this.input.nativeElement.select();
  }

}

Есть ли ловушка жизненного цикла, которая запускается один раз после инициализации компонентов, но после загрузки двустороннего связывания?

1 Ответ

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

на самом деле, использование setTimeout() - это не хакерское решение , это решение.из-за правила однонаправленного потока данных angular .

правило потока однонаправленных данных Angular запрещает обновление представления после его составления.

в порядкечтобы наблюдать последствия этого правила, попробуйте присвоить новое значение свойству info ChildComponent на AfterViewInit hook.вы получите ExpressionChangedAfterItHasBeenCheckedError, который является угловым способом сказать, что «обновление представления после его составления запрещено!»

, поскольку вы не обновляете какие-либо свойства привязки к данным вашего компонента и простоделая манипуляции с dom, angular не выдает никаких ошибок, но он также не отражает ваши изменения в dom.

возвращаясь к вашему вопросу;

Есть ли хук жизненного цикла, который работаетодин раз после инициализации компонентов, но после загрузки двусторонней привязки?

да есть и это AfterViewInit hook.Потому что;

Просмотр запросов устанавливается до вызова обратного вызова ngAfterViewInit.

и обновления DOM обрабатываются до вызова ngAfterViewInit, как объяснено в здесь .

и он приходит после OnChanges hook, где;

OnChanges вызывается, когда любое привязанное к данным свойство объектадиректива изменяется.

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

ngAfterViewInit() {
  setTimeout(() => this.input.nativeElement.select());
}

, если вы хотите выделить текствсякий раз, когда свойство input изменяется родительским компонентом (включая первую загрузку), вам необходимо реализовать OnChanges hook.

ngOnChanges() {
  setTimeout(() => this.input.nativeElement.select());
}

- вот рабочая демонстрация https://stackblitz.com/edit/angular-owahps

надеюсь, чтопомогает.

...