【问题标题】:Custom structural directive creates too many elements自定义结构指令创建了太多元素
【发布时间】:2019-03-18 22:48:29
【问题描述】:

我创建了我的自定义结构指令,它应该为传递的项目数组中的每个元素呈现宿主元素:

@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-qwatckstackblitz 来显示这个问题。

为什么会这样,应该如何正确完成?

【问题讨论】:

    标签: angular angular-directive


    【解决方案1】:

    目前,已完成以下工作:

    1. 指令实例已创建
    2. NgOnChanges 被调用
    3. NgOnInit 被调用

    所以基本上,一旦您为收藏创建了 N 个视图,您就可以在 NgOninit 期间再创建一个,从而在您的模板中生成 N+1 个嵌入视图。

    只需删除NgOnInit的内容。

    【讨论】:

    • 谢谢。我认为ngOnChanges()ngOnInit() 之后被调用,因此“空”元素应该在开始时,但我错了。
    【解决方案2】:

    你为什么要在ngOnInit 中创建这个,因为这会创建额外的一个。评论此行后,多余的项目将消失。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-08-16
      • 2017-05-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多