将 #element 绑定到使用 *ngFor 创建的元素

Posted

技术标签:

【中文标题】将 #element 绑定到使用 *ngFor 创建的元素【英文标题】:bind #element to element created with *ngFor 【发布时间】:2018-04-12 13:01:08 【问题描述】:

我正在使用 *ngFor 创建一堆 div。我想把手放在其中一个上,看看它的宽度。

.html
<div #elReference *ngFor="let el of elements> HEHE </div>

.ts
  @ViewChild("elReference") elReference: ElementRef;

显然,您不能将 ViewChild 与 *ngFor 一起使用,因为 elReference 仍未定义。

如何获得使用 *ngFor 创建的元素引用?

【问题讨论】:

看看这个帖子:***.com/questions/40165294/… 谢谢。我试过 @ViewChildren("elReference") elReferences: QueryList; ,但仍然得到一个未定义的 elReferences 值。 我在 onInit() 中使用了它。看来 ngAfterViewInit 是强制性的。 你必须使用 ngAfterViewInit 因为你必须等待模板被解析和 DOM 被挂载。 谢谢。我现在确实得到了clientWidth。由于某种原因,它被四舍五入到最接近的整数。此代码 console.log(this.elReference.nativeElement.clientWidth);返回 25,尽管浏览器中的实际宽度是 25.11。 $("element").outerwidth() 也返回 25.11 【参考方案1】:

没有办法选择性地添加模板变量, 但您可以有选择地添加标记,然后按此过滤:

<div #elReference [attr.foo]="el.x == 'foo' ? true : null" *ngFor="let el of elements> HEHE </div>
@ViewChildren("elReference") elReference: QueryList<ElementRef>;

ngAfterViewInit() 
  console.log(this.elReference.toArray()
      .filter(r => r.nativeElement.hasAttribute('foo')));

【讨论】:

Danke schön。到目前为止,我一直在 onInit() 中使用 ViewChild 和#elReference。为什么在这种情况下我需要使用 ngAfterViewInit? 如果*ngFor 依赖于传递给@Input() 的数据,它还不会被渲染。 toArray() 不是 javascript 函数,TypeScript 按预期返回错误 @M98 toArray() 是由@ViewChildren 创建的QueryList 的方法。我应该更清楚地回答这个问题。 好的,现在有了编辑,这很有意义!非常感谢【参考方案2】:

指令有一个更复杂但更正确的方法。

<!-- app.component.html -->
<div *ngFor="let el of elements" [id]="el.id"> HEHE </div>
// div-id.directive.ts
import  Directive, Input, ElementRef  from '@angular/core';

@Directive(
  selector: 'div[id]',
)
export class DivIdDirective 
  @Input() id: number;

  constructor(ref: ElementRef<HTMLDivElement>) 
    this.el = ref.nativeElement;
  

  el: HTMLDivElement;


// app.component.ts
export class AppComponent implements AfterViewInit 
  // ...
  @ViewChildren(DivIdDirective) els: QueryList<DivIdDirective>;

  ngAfterViewInit(): void 
    console.log(this.els.map((id, el) => (id, el));
  


【讨论】:

以上是关于将 #element 绑定到使用 *ngFor 创建的元素的主要内容,如果未能解决你的问题,请参考以下文章

*ngFor 如何使用索引将数组中的每个项目绑定到 ngModel

如何将图像源绑定到 ngFor 循环内的可观察对象?

使用字符串插值将控件从FormGroup绑定到* ngFor内的模板

Angular *ngFor 使用异步管道绑定到 observable - 发生了啥?

Angular NgFor 仅支持绑定到 Iterables,例如 Arrays

如何以角度将数据与ngFor绑定