جاوااسکریپت - حلقه زدن در Angular QueryList


پس من میخواهم تمام تصاویر موجود در کامپوننت خود را در یک آرایه بدست آورم، بنابراین از @ViewChildren در Angular استفاده میکنم که یک QueryList از ElementRef برمیگرداند:

@ViewChildren('img', { read: ElementRef }) images: QueryList<ElementRef>;

با این حال، هر زمان که تلاش میکنم از طریق لیست حلقه بزنم، به نظر نمیرسد که بتوانم nativeElement را به دست آورم. من این را در ngAfterViewInit() فراخوانی میکنم

this.images.forEach((img, index) => console.log("Image", img.nativeElement));

من هیچ چیزی در console.log نمیگیرم، نه خطایی نه هیچ چیزی.

این به نوبه خود کار میکند:

console.log("this.images", this.images);

در زیر تصویری از لاگ console.log("this.images", this.images) آمده است:

اینجا html است:

<div class="swiper-slide" *ngFor="let exhibit of exhibits; let i = index">
   <app-exhibit-images exhibitImagesId="{{ exhibit.fields.eventImages[0].sys.id }}" [eventPicturesStart]="eventPicturesStart" (sendEndEventPictures)="getEndEventImages($event)"></app-exhibit-images>
   <div id="exhibit-{{i}}"class="gallery__content" [ngClass]="{'show-event-pictures' : eventPicturesStart}">
      <div class="gallery__poster" [ngClass]="{'gallery-expand' : isGalleryExpanded }">
         <figure class="poster__image">
            <picture>
               <source srcset="{{ exhibit.fields.photo.fields.file.url }}" type="img/png">
               <img #img src="{{ exhibit.fields.photo.fields.file.url }}" alt="{{ exhibit.fields.photo.fields.description }}">
            </picture>
         </figure>
      </div>
      <div class="gallery__text" [ngClass]="{'gallery-expand' : isGalleryExpanded }">
         <button class="gallery-expand-button" (click)="expandGallery()"></button>
         <h2 class="gallery__heading">{{ exhibit.fields.title }}</h2>
         <h3 class="gallery__subheading">{{ exhibit.fields.subTitle }}</h3>
         <h4 class="gallery__artist">{{ exhibit.fields.artist }}</h4>
         <p class="gallery__description" *ngIf="exhibit.fields.description">{{ exhibit.fields.description }}</p>
      </div>
   </div>
</div>

من چه چیزی را از دست دادهام؟

پاسخ شماره ۱

من با مشکلی مشابه با @ContentChildren مواجه شدم. راه حل این بود که به observable changes از QueryList مشترک شوید.

در اصل، این هر زمان که هر یک از وضعیتهای فرزندان تغییر کند، فعال میشود. معمولاً این ضروری نیست اما اگر لیست فرزندان شما از طریق یک GET بارگذاری شود، این اطمینان حاصل میکند که دادههای QueryList قبل از اجرا روی آن بارگذاری شدهاند. مهم است که توجه داشته باشید اشتراک دوباره فعال میشود هر زمانی که محتوای هر یک از فرزندان تغییر کند.

@ContentChildren(forwardRef(() => ChildComponent), { descendants: true })
private children: QueryList<ChildComponent>;

ngAfterContentInit() {
    // subscribe to changes
    this.children.changes.subscribe(children => {
        children.forEach(child => {
            // do something with each child...
        });
    });
}

پاسخ شماره ۲

همانطور که @Jakopo Sciampi قبلاً اشاره کرد، یک احتمال دیگر هم استفاده از تابع .toArray() روی QueryList است.

this.images.toArray().forEach((img, index) => {
            console.log('Image', img.nativeElement);
        });

فقط مطمئن شوید که فرمان را خیلی زود فرا نخوانید => هیچ عنصری وجود نخواهد داشت => حلقه اجرا نمیشود.