One place for hosting & domains

      Используйте ViewChild в Angular для доступа к дочернему компоненту, директиве или элементу DOM


      Введение

      В этой статье мы познакомим вас с декоратором Angular ViewChild.

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

      Использование ViewChild с директивами

      ViewChild открывает возможность доступа к директивам.

      Допустим, у нас имеется директива SharkDirective.

      В идеале мы используем @angular/cli для генерирования директивы:

      • ng generate directive shark

      В противном случае необходимо добавить ее вручную в app.module.ts:

      app.module.ts

      import { SharkDirective } from './shark.directive';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          SharkDirective
        ],
        ...
      })
      

      Наша директива будет искать элементы с атрибутом appShark и добавлять в начало текста элемента слово Shark:

      shark.directive.ts

      import {
        Directive,
        ElementRef,
        Renderer2
      } from '@angular/core';
      
      @Directive(
        { selector: '[appShark]' }
      )
      export class SharkDirective {
        creature="Dolphin";
      
        constructor(elem: ElementRef, renderer: Renderer2) {
          let shark = renderer.createText('Shark ');
          renderer.appendChild(elem.nativeElement, shark);
        }
      }
      

      Затем мы добавим Shark в Fin, используя его в шаблоне компонента:

      app.component.html

      <span appShark>Fin!</span>
      

      При просмотре приложения в браузере оно будет выглядеть так:

      Output

      Shark Fin!

      Теперь мы можем получить доступ к переменной экземпляра creature директивы SharkDirective и задать переменную экземпляра extraCreature с ее значением:

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { SharkDirective } from './shark.directive';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        extraCreature: string;
      
        @ViewChild(SharkDirective)
        set appShark(directive: SharkDirective) {
          this.extraCreature = directive.creature;
        };
      
        ngAfterViewInit() {
          console.log(this.extraCreature); // Dolphin
        }
      }
      

      Здесь мы использовали задающий метод, чтобы задать переменную extraCreature. Обратите внимание, что мы ждем, пока блок жизненного цикла AfterViewInit не получит доступ к нашей переменной, поскольку тогда станут доступными дочерние компоненты и директивы.

      При просмотре приложения в браузере мы видим "Shark Fin!", сообщение. Однако в журнале консоли отображается следующее:

      Output

      Dolphin

      Родительскому компоненту удалось получить доступ к значению из директивы.

      Использование ViewChild с элементами DOM

      ViewChild предоставляет возможность доступа к элементам модели DOM, имеющим шаблонную переменную.

      Допустим в нашем шаблоне имеется <input> с шаблонной переменной #someInput:

      app.component.html

      <input #someInput placeholder="Your favorite sea creature">
      

      Теперь мы можем получить доступ к <input> с помощью ViewChild и задать значение:

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit,
        ElementRef
      } from '@angular/core';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css']
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild('someInput') someInput: ElementRef;
        ngAfterViewInit() {
          this.someInput.nativeElement.value="Whale!";
        }
      }
      

      Когда срабатывает ngAfterViewInit, для <input> задается следующее значение:

      Output

      Whale!

      Родительскому компоненту удалось задать значение дочернего элемента DOM.

      Использование ViewChild с дочерними компонентами

      ViewChild обеспечивает возможность доступа к дочернему компоненту и методам вызова или доступа к переменным экземпляра, которые доступны дочернему элементу.

      Допустим, у нас имеется компонент ChildComponent. В идеале мы используем @angular/cli для генерирования компонента:

      • ng generate component child --flat

      В противном случае вам может понадобиться создать файлы child.component.css и child.component.html и вручную добавить их в app.module.ts:

      app.module.ts

      import { ChildComponent } from './child.component';
      ...
      @NgModule({
        declarations: [
          AppComponent,
          ChildComponent
        ],
        ...
      })
      

      Мы добавим метод whoAmI в компонент ChildComponent, который возвращает следующее сообщение:

      child.component.ts

      whoAmI() {
        return 'I am a child component!';
      }
      

      Далее мы разместим ссылку на компонент в нашем шаблоне приложения:

      app.component.html

      <app-child>child works!</app-child>
      

      Теперь мы можем вызвать метод whoAmI внутри класса родительского компонента с помощью ViewChild, как показано здесь:

      app.component.ts

      import {
        Component,
        ViewChild,
        AfterViewInit
      } from '@angular/core';
      import { ChildComponent } from './child.component';
      
      @Component({
        selector: 'app-root',
        templateUrl: './app.component.html',
        styleUrls: ['./app.component.css'],
      })
      export class AppComponent implements AfterViewInit {
        @ViewChild(ChildComponent) child: ChildComponent;
        ngAfterViewInit() {
          console.log(this.child.whoAmI()); // I am a child component!
        }
      }
      

      При просмотре приложения в браузере отображается журнал консоли:

      Output

      I am a child component!

      Родительскому компоненту удалось вызвать метод whoAmI дочернего компонента.

      Заключение

      Вы научились использовать ViewChild для доступа к директиве, дочернему компоненту и элементу DOM из класса родительского компонента.

      Если шаблон динамически изменится на новый элемент, ViewChild автоматически обновит шаблон.

      Если вам требуется доступ к нескольким дочерним элементам, вам следует использовать метод ViewChildren.

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



      Source link