Angular:从组件中的ngFor循环中获取新的DOM元素

时间:2017-08-18 22:38:58

标签: angular typescript dom element

我无法完成一件在理论上应该很容易的事情,而且这真的让我烦恼。

基本上,我有一个为数组提供一些数据的服务,让我们把它简化为一个字符串数组:

public myList: string[] = ['lorem', 'ipsum'];

在我的模板中,我正在为数组中的每个条目创建列表项并分配ID:

<ul id="listGroup">
  <li ngFor="let item of myList" [attr.id]="'item-'+item">{{ item }}</li>
</ul>

现在,我有一些额外的功能,它扩展了列表并添加了新项目。 我接下来基本上想要做的是,访问由于新项目被推送到列表而创建的每个新DOM元素。

我通过使用ElementRef和nativeElement的querySelector方法尝试了这一点。 我只想说我已经在我的组件中订阅了一些内容,它通知我数组中新添加的项目,它还提供了相应的值,以便我可以编译正确的元素ID:

this.elementRef.nativeElement.querySelector('#item-'+item);

总而言之,我将它放在ngAfterViewInit()生命周期钩子中,并假设我会找到每个新添加的DOM元素。但是没有!我总是得到一个“未定义”的回报。所以似乎DOM元素还没有可用,我如何正确地“等待”元素存在并可以被我的组件访问?

我希望这能清楚地表明我的问题是什么,如果不是,我可能需要添加更多代码,虽然在移动设备上虽然有点。

感谢您的帮助!

安迪

1 个答案:

答案 0 :(得分:1)

以下是如何获取元素参考的示例。你可以适应你的情况:

打字稿指令

  .....

  @Input('focusOnInit') priority: number = 0;

  static instances: FocusOnInitDirective[] = [];

  constructor(public renderer: Renderer, public elementRef: ElementRef) {
  }

  ngOnInit(): void {
    FocusOnInitDirective.instances.push(this)
  }

 ngAfterViewInit(): void {
    setTimeout(() => {
      FocusOnInitDirective.instances.splice(FocusOnInitDirective.instances.indexOf(this), 1);
    });

    if (FocusOnInitDirective.instances.every((i) => this.priority >= i.priority)) {
      this.renderer.invokeElementMethod(
        this.elementRef.nativeElement, 'focus', []);
    }
  }
}

<强> HTML

<button type="button" (click)=add()>Add</button>
<div *ngFor="let input of inputs">
  <input type="text" focusOnInit="3">
  <input type="text" focusOnInit="2">
  <input type="text" focusOnInit="1">
</div>

组件打字稿:

  ....
  inputs = [];

  add() {
    this.inputs.push(this.inputs.length+1);
  }

plunker