Пользовательская структурная директива создает слишком много элементов - PullRequest
0 голосов
/ 14 октября 2018

Я создал свою пользовательскую структурную директиву, которая должна отображать хост-элемент для каждого элемента в переданном массиве элементов:

@Directive({
  selector: '[appItems]'
})
export class ItemsDirective implements OnInit, OnChanges {

  @Input('appItemsOf')
  items: any[];

  constructor(private container: ViewContainerRef,
              private template: TemplateRef<any>) {
  }

  ngOnInit(): void {
    this.container.createEmbeddedView(this.template);
  }

  ngOnChanges(): void {
    this.container.clear();

    for (const item of this.items) {
      if (item) {
        this.container.createEmbeddedView(this.template, {
          $implicit: item,
          index: this.items.indexOf(item)
        });
      }
    }
  }
}

Использование:

<div *appItems="let item of items">
  Item: {{ item.name }}
</div>

Который, к сожалению, печатает:

Item: 1
Item: 2
Item: 3
Item:

Последний элемент создается и отображается, хотя массив элементов выглядит следующим образом:

items = [
    {
        name: '1'
    },
    {
        name: '2'
    },
    {
        name: '3'
    }
]

Я создал https://stackblitz.com/edit/angular-qwatck stackblitz , показывающий эту проблему.

Почему это так и как это должно быть сделано правильно?

Ответы [ 2 ]

0 голосов
/ 14 октября 2018

В настоящее время выполняется следующее:

  1. Создается экземпляр директивы
  2. NgOnChanges вызывается
  3. NgOnInit вызывается

Таким образом, как правило, после создания N-представлений для вашей коллекции вы создаете еще одно во время NgOninit, в результате чего генерируется N + 1 встроенных представлений в шаблоне.

Просто удалитесодержание NgOnInit.

0 голосов
/ 14 октября 2018

Почему вы создаете это в ngOnInit, так как это создает дополнительный.После комментирования этой строки лишний элемент исчезнет.

  ngOnInit(): void {
    // this.container.createEmbeddedView(this.template);
  }
...