angular - HTML'den çağrılan Angular get Metodu sonsuz yeniden yükleme döngüsüne neden oluyor


Şu anda, açmak için belgelere bağlantılar doldurmam gereken dinamik sayıda düğme gerektiren bir proje üzerinde çalışıyorum.

<tr *ngFor="let competence of competences; let i = index">{{competence.name.de}}
  <td *ngFor="let competenceLevel of levels; let j = index">
    <button type="button" *ngFor="let learnRecommendation of getLearnRecommendationsByIndex(i,j)" (click)="openDialog(learnRecommendation)">{{learnRecommendation.title | translateText}}</button>
  </td>
</tr>

Bu, tabloyu butonlarla doğru şekilde dolduruyor ve doğru adı gösteriyor, ancak butonlara eklemeye çalıştığım hiçbir Etkinlik çalışmıyor. (click) olayına ihtiyacım var ama test için (onload) gibi şeyleri de denedim ve onlar da çalışmıyor. Sonunda fark ettim ki, tüm butonlar sürekli olarak yeniden yükleniyor. Bir arkadaşım, bunun kullandığım get yöntemiyle bağlantılı olabileceğini söyledi, ama nasıl olduğunu anlamıyorum. Her türlü yardım çok takdir edilecektir.

Cevap #1

Bu, Angular değişim tespiti ile ilgili bir sorundur.

Angular, getLearnRecommendationsByIndexfunction çalıştırılana kadar getLearnRecommendationsByIndexis sonucunun değişip değişmediğini tespit edemez.

Bu yüzden döndürülen değeri almak ve hiçbir şeyin değişmediğinden emin olmak için her değişiklik tespit döngüsünde bunu çalıştırması gerekir.

Aynı şey, bir getter veya setter kullandığınızda da geçerlidir. Bu, özellikle işlevin https çağrılarından bir koleksiyon döndürmesi durumunda sorunludur, çünkü çağrı her döngüde bir kez gerçekleşerek uygulamanın yanıtsız hale gelmesine neden olur.

Daha da kötüsü? Döndürülen değerler aynı olsa bile, yeni nesnelerse (bir observable'ın döndüreceği gibi), Angular değişiklikler olduğunu varsayar ve DOM yeniden oluşturulur.

Bunu önlemek için OnPush değişiklik algılama stratejisini kullanabilirsiniz

Örnek :

@Component({
  selector: 'some-selector',
  templateUrl: 'someurl' ,
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class OnPushDetComponent { 

  constructor(private cdr: ChangeDetectorRef) {

  }

  runChangeDetection() {
      this.cdr.detectChanges();
  }

}

Unutmayın ki görünümünüz yalnızca ChangeDetection'ı çalıştırdığınızda güncellenecek, otomatik olarak değil.

Yapabileceğiniz bir diğer şey, dönüş değerlerini bir diziye yakalamak ve o diziyi görünümünüzde kullanmaktır.