Açısal olarak değişiklik algılamayı manuel olarak tetikleme


387

Bir özelliği olan bir Açısal bileşen yazıyorum Mode(): string.

Herhangi bir olaya yanıt olarak bu özelliği programlı olarak ayarlayabilmek istiyorum.

Sorun, bir tarayıcı olayı olmadığında, şablon bağlamanın {{Mode}}güncellenmemesi.

Bu değişiklik algılamayı manuel olarak tetiklemenin bir yolu var mı?

Yanıtlar:


640

Bunlardan birini deneyin:

  • ApplicationRef.tick()- AngularJS'lere benzer $rootScope.$digest()- yani, tüm bileşen ağacını kontrol edin
  • NgZone.run(callback)- benzer $rootScope.$apply(callback)- yani, Açısal bölge içindeki geri arama işlevini değerlendirin. Bence, ama emin değilim, bu geri arama işlevini yürüttükten sonra tam bileşen ağacı kontrol sonuçlanır.
  • ChangeDetectorRef.detectChanges()- benzer $scope.$digest()- yani, sadece bu bileşeni ve çocuklarını kontrol edin

Sen enjekte edebilir ApplicationRef, NgZoneya ChangeDetectorRefda bileşen içine.


1
Teşekkürler, her şeyi kontrol etmemek için 3. çözümü seçtim, çünkü değişiklikler oldukça yerelleştirildi. Daha fazla zamanım olduğunda diğer seçenekleri araştırmalıyım. Her seçimde herhangi bir performans etkisi var mı?
jz87

36
İçin +1 ChangeDetectorRef.detectChanges(). doğrulayıcılar direktifimin bir girdinin değerini güncelleyebilmesi için tetikleniyordu.
ps2goat

7
ApplicationRef.tick () ve ChangeDetectorRef.detectChanges () hala 2.0.0 finalinde mevcut.
Max Mumford

51
Sadece bundan söz edeceğimi düşündüm. Bunlar statik yöntemler değil, örnek yöntemler. Bu sınıfları hizmet olarak enjekte etmeniz gerekecek.
Stephen Paul

1
ApplicationRef.tick (), FireFox v17 (<20) ile ilgili bir sorunun çözülmesine yardımcı oldu
Dan J

123

Kabul edilen cevap referansını kullandım ve bir örnek vermek istiyorum, çünkü Açısal 2 belgelerinin okunması çok zor, umarım bu daha kolay:

  1. İçe Aktar NgZone:

    import { Component, NgZone } from '@angular/core';
    
  2. Sınıf kurucunuza ekleyin

    constructor(public zone: NgZone, ...args){}
    
  3. Kodu şununla çalıştır zone.run:

    this.zone.run(() => this.donations = donations)
    

6
zone.runkodu nereye koymalısınız ve tam olarak donationsnedir?
suku

@suku donations, güncellemek istediğiniz herhangi bir mülktür, bu yüzden this.foo = bar olabilir. zone.run, öğeleri güncellemek istediğiniz yere gider.
Matthew Optional Meehan

4
Bu çözümü document.addEventListener ("özgeçmiş", geri arama) kullanırken bir görünüm güncellemesini zorlamak için kullandım
marcovtwout

71

MarkForCheck () ile güncelleyebildim

Import ChangeDetectorRef

import { ChangeDetectorRef } from '@angular/core';

Enjekte edin ve başlatın

constructor(private ref: ChangeDetectorRef) { 
}

Son olarak gerçekleşecek değişiklik tespitini işaretleyin

this.ref.markForCheck();

İşte markForCheck () işlevinin çalıştığı ve detChanges () işlevinin çalışmadığı bir örnek.

https://plnkr.co/edit/RfJwHqEVJcMU9ku9XNE7?p=preview

DÜZENLEME: Bu örnek, sorunu artık tasvir etmiyor :( Bence düzeltildiği yerde daha yeni bir Açısal sürüm çalışıyor olabilir.

(Tekrar çalıştırmak için STOP / RUN tuşuna basın)


DetectChanges () için Goo noktası çalışmıyor. Aynı sorunu fark ettim ve değişiklik tespiti OnPush değilse işe yaradığını gördüm. Bunun için bir açıklama almak iyi olurdu ...
Christian

2
DetChanges aslında bu dalgıçta çalışıyor gibi görünüyor? Bir şey mi kaçırıyorum?
Jared_C

1
ChangeDetectorRef'in yalnızca Bileşenler'de çalıştığını not etmelisiniz
kevinius

(!) Bu kötü bir örnek, üzgünüm. Örnek hiçbir şey göstermiyor. İlk öğenin üzerine yazılır. Sadece zamanlayıcıları biraz ayarlayın ...
Peter Stegnar

Bu örnek, sorunu artık tasvir etmiyor :( Bence düzeltildiği yerde daha yeni bir Açısal sürüm çalıştırıyor olabilir.
Nuno Tomas

7

Angular 2+ sürümünde @Input dekoratörünü deneyin

Ana ve alt bileşenler arasında hoş bir özellik bağlayıcılığına izin verir.

İlk olarak alt öğeye iletilecek nesneyi / özelliği tutmak için üst öğede genel bir değişken oluşturun.

Sonra alt öğeden geçirilen nesneyi / özelliği tutmak için alt öğede genel bir değişken oluşturun.

Ardından, alt şablonun kullanıldığı üst html'de, alt değişkenin adıyla köşeli parantez gösterimi ekleyin ve ardından üst değişkenin adına eşit olarak ayarlayın. Misal:

<child-component-template [childVariable] = parentVariable>
</child-component-template>

Son olarak, child özelliğinin alt bileşende tanımlandığı yerde, Giriş dekoratörünü ekleyin:

@Input()
public childVariable: any

Üst değişkeniniz güncellendiğinde, güncelleştirmeleri html'sini güncelleyecek olan alt bileşene iletmelidir.

Ayrıca, alt bileşende bir işlevi tetiklemek için ngOnChanges'e bakın.


2
HAYIR ... bu sorun ... eğer ebeveyn güncellerseniz ... exmaple için statik bir yöntemde "referans ile" güncellendi çocuk demek değişiklik algılama meydana
gelmedi

Aynı sorunu günlerce yaşıyorum. Ben PHP arka ucundan veri almaya çalışın ve veri hiç Güncelleme yok. Microsoft Edge'de iyi çalışıyor, ancak diğer tarayıcıda çalışmıyor. İlk başladığımda veri almaya devam ediyorum ama veri değişirse görünümde güncellenmiyor
el6976

1

ChangeDetectorRef.detectChanges () - $ scope. $ Digest () benzeri - yani, sadece bu bileşeni ve alt öğelerini kontrol edin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.