javascript Angular -如何在 *ngFor指令中获取HTML元素

w7t8yxp5  于 12个月前  发布在  Java
关注(0)|答案(2)|浏览(75)

我无法在使用了“*ngFor”指令的树中使用“document.querySelectorAll('. box-message')”获取“box-message”类。
我正在发出一个“http rest”请求,在请求之后,“*ngFor”指令完成了房子的建造,之后我试图使用“document.querySelectorAll('. box-message')”获取“box-message”类。
但据我所知(但我可能是错的),房子没有时间来建造,这就是为什么我没有收到“框消息”类。
我试过使用AfterViewInit,但它没有帮助。
如何解决这一问题?

HTML

<ul class="ul-ads">
      <li class="li-ads" *ngFor="let ads of ads">
        <div class="box-message">{{ads.message}}</div>
      </li>
    </ul>

脚本

export class AdsComponent implements OnInit {

          ads!: Ads[];


          public getAds(): Observable<any> {

            return this.http.get<any>(`http://localhost:8080/apis/data/ads`,
              {observe: 'response'});

          }

          ngOnInit(): void {

            this.getAds().subscribe({

              next: data => {

                this.ads = responseData.body.content;

                const boxMessage = document.querySelectorAll('.box-message');
                console.log(boxMessage) // NodeList[]

              }

            });

          }

        }

9o685dep

9o685dep1#

您可以利用ViewChildren来实现这一点。
在您的模板中。为每个框消息添加引用:

<ul class="ul-ads">
  <li class="li-ads" *ngFor="let ads of ads">
     <div #boxMessage class="box-message">{{ads.message}}</div>
  </li>
</ul>

在你的组件中,添加一个属性来保存视图子视图并订阅changes observable:

@ViewChildren('boxMessage')
boxMessages: QueryList<ElementRef>;

ngAfterViewInit(): void {
  this.boxMessages.changes.subscribe(boxMessage => {
    // your code here
  });
}

任何时候视图子视图被改变,你的代码将在子视图被呈现后执行。

  • 不需要使用setTimeout来引入人为延迟。*

希望能帮到你。

um6iljoc

um6iljoc2#

你需要“等待”Angular repaint。一般来说,你使用的是没有毫秒的设置。

...
next: data => {
    this.ads = responseData.body.content;
    setTimeout(()=>{
       const boxMessage = document.querySelectorAll('.box-message');
       console.log(boxMessage) // NodeList[]
       console.log(this.ads.message) // to print data 
    })
  }

认为angular执行subscribe下的指令,然后重新绘制。这就是为什么你没有得到元素。
重要:在Angular中,我们很少需要使用旧的JavaScript方式document.getElementBy。可以使用模板引用变量声明ViewChildren

<ul class="ul-ads">
      <li class="li-ads" *ngFor="let ads of ads">
        <!--see the #item-->
        <div #item class="box-message">{{ads.message}}</div>
      </li>
   </ul>

然后您可以在QueryList中获取所有这些

@ViewChildren('item') items!:QueryList<ElementRef>

在elementRef中,nativeElement属性是html标记
一个Query list允许转换为数组,重新排序,获得第一个和最后一个元素,订阅更改...

ngAfterViewInit()
{
     this.items.changes.subscribe(_=>{
         console.log(this.items.first.nativeElement)
         console.log(this.items.last.nativeElement)
         //the third element
         const htmlElement=this.items.find((_,index)=>index==2)?.nativeElement
         ...

     })
}

相关问题