angular
March 20

ViewContainerRef в Angular

Для программной вставки компонента или шаблона можно использовать сервис ViewContainerRef. Разберем как с ним работать, но для понимания концепции начнем разбор с чистого JavaScript. Исходя из предложенной разметки, ваша задача - добавить новый параграф рядом с текущим.

<p class=”one”>Element one</p>

Используя jQuery это можно сделать одной строчкой кода:

$('<p>Element two</p>').insertAfter('.one');

Если мы хотим вставить элемент в DOM, нужно знать куда именно. Не важно что используется: JS или Angular. Принцип всегда один и тот же. Используя ViewContainerRef вставку можно осуществить следующим образом:

ViewContainerRef и DI

@Component({
  selector: 'vcr',
  template: `
    <template #tpl>
      <h1>ViewContainerRef</h1>
    </template>
  `,
})
export class VcrComponent {
  @ViewChild('tpl') tpl;
  constructor(private _vcr: ViewContainerRef) {
  }
  
  ngAfterViewInit() {
    this._vcr.createEmbeddedView(this.tpl);
  }
}

@Component({
  selector: 'my-app',
  template: `
      <vcr></vcr>
  `,
})
export class App {

}

Мы внедрили сервис в компонент. В этом случае контейнер будет ссылаться на ваш элемент-хост (vcr), и шаблон будет вставлен как соседний элемент к элементу vcr.

ViewContainerRef и ViewChild

@Component({
  selector: 'vcr',
  template: `
    <template #tpl>
      <h1>ViewContainerRef</h1>
    </template>
    <div>Some element</div>
    <div #container></div>
  
  `,
})
export class VcrComponent {
  @ViewChild('container', { read: ViewContainerRef }) _vcr;
  @ViewChild('tpl') tpl;

  ngAfterViewInit() {
    this._vcr.createEmbeddedView(this.tpl);
  }
}

@Component({
  selector: 'my-app',
  template: `
    <div>
      <vcr></vcr>
    </div>
  `,
})
export class App {

}


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

Можно посмотреть в консоли, из чего состоит ViewContainerRef:

Это вольный перевод оригинального материала