angular - ngFor yönergesini arayüzü nesne tipini kaybetmeden genişletmek


Uygulamamızda, her nesnenin ona bağlı benzersiz bir ID'si vardır. Oluşan büyük listelerin render edilmesine yardımcı olmak için (ki bunlardan çok sayıda vardır), uygulamamızdaki tüm şablonlanmış *ngFor döngüleri için trackby fonksiyonlarını kullanmaya karar verdim.

Yinelenen trackby fonksiyonlarını azaltmak için en iyi hareket tarzının, bunu otomatik olarak yapan özel bir ngFor* direktifi oluşturmak olduğuna karar verdim; eğer söz konusu nesnenin bir ID'si varsa veya bir indeksi varsa (iş mantığı bunu gerektiriyor), özel trackby ekleyecektir.

Bu işe yarıyor ve trackby, umduğum gibi ekleniyor. Ancak, özel *ngFor kullanırken, şablon içindeki NgIterable nesnesinde türlemenin kaybolduğunu fark ettim ve nedenini bilmiyorum, çünkü kullanım örnekleriyle genişletiyorum.

İşte özel yönerge:

import {
  Directive,
  Input,
  IterableDiffers,
  NgIterable,
  TemplateRef,
  TrackByFunction,
  ViewContainerRef,
} from "@angular/core";

import { NgFor, NgForOfContext } from "@angular/common";
import { InfiniteScrollItem } from "@shared/lists";

@Directive({
  selector: "[dpsNgFor][[dpsNgForOf]]",
  standalone: true,
})
export class DpsNgForDirective<T, U extends NgIterable<T> = NgIterable<T>> extends NgFor<T, U> {
  public _trackBy(index: number, item: any) {
    const _isScrollItem = (object: InfiniteScrollItem<T> | never) => "item" in object && "index" in object;
    const _hasId = (object: InfiniteScrollItem<T> | never) => "id" in object;

    // If it's an infinite scroll object, use the item.index;
    if (_isScrollItem(item)) {
      return item.index;
    }

    // Not an infinite scroll item
    if (_hasId(item)) {
      // Use the object id (if it has one).
      return item.id;
    }
    // Fall back to index if id isn't found natively in the object.
    return index;
  }

  @Input()
  set dpsNgForOf(value) {
    super.ngForOf = value;
  }

  @Input()
  set dpsNgForTrackBy(trackBy: TrackByFunction<T>) {
    super.ngForTrackBy = trackBy;
  }

  constructor(
    public _viewContainer2: ViewContainerRef,
    public _templateRef2: TemplateRef<NgForOfContext<T, U>>,
    public _differs2: IterableDiffers
  ) {
    super(_viewContainer2, _templateRef2, _differs2);
    super.ngForTrackBy = this._trackBy;
  }
}

Herhangi bir yardım takdir edilir veya doğru yönlendirilirse sevinirim.

Düzeltme: "arayüz yazımı kayboldu" derken ne demek istediğime dair bazı örnekler işte burada.

Bu, arayüzün normal bir ngFor ile uygun şekilde tiplenmiş olduğunda genellikle nasıl göründüğüdür

Ve işte özel ngFor direktifiyle nasıl göründüğü. İkisi de doğru bir şekilde yineleme yapma amacına ulaşıyor. Bu sadece nesne ile ilişkili olan tür bilgisini kaybetti.

Cevap #1

Meğerse, value değişkeninde tip belirlemem gerekiyormuş, böylece sonunda aşağıdaki gibi görünüyordu:

  @Input()
  set dpsNgForOf(value: U & NgIterable<T>) {
    super.ngForOf = value;
  }