AngularJS'de, $watch
işlevini kullanarak kapsam değişkenlerindeki değişiklikleri gözlemlemek için gözlemcileri belirtebilirsiniz $scope
. Açısal'da değişken değişiklikleri (örneğin, bileşen değişkenlerinde) izlemenin karşılığı nedir?
AngularJS'de, $watch
işlevini kullanarak kapsam değişkenlerindeki değişiklikleri gözlemlemek için gözlemcileri belirtebilirsiniz $scope
. Açısal'da değişken değişiklikleri (örneğin, bileşen değişkenlerinde) izlemenin karşılığı nedir?
Yanıtlar:
Açısal 2'de değişiklik algılama otomatiktir ... $scope.$watch()
ve $scope.$digest()
RIP
Maalesef, geliştirici kılavuzunun Değişiklik Algılama bölümü henüz yazılmamıştır ( Mimariye Genel Bakış sayfasının altında, "Diğer Öğeler" bölümünde bir yer tutucu vardır ).
Değişiklik algılamanın nasıl çalıştığını anlayacağım:
setTimeout()
bizim gibi yamalar gibi bir şeyden ziyade bileşenlerimizde kullanabiliriz $timeout
çünkü setTimeout()
maymun yamalı.ChangeDetectorRef
.) Bu değişiklik dedektörleri, Angular bileşenler oluşturduğunda oluşturulur. Kirli kontrol için, tüm bağlantılarınızın durumunu takip ederler. Bunlar, bir anlamda, $watches()
Açısal 1'in {{}}
şablon bağlamaları için ayarlayacağı otomatikliğe benzer . onPush
bileşenlerinizin hiçbirinde değişiklik algılama stratejisini kullanmıyorsanız ), ağaçtaki her bileşen bir kez (TTL = 1) ... üstten, derinlik-birinci sırayla incelenir. ( Geliştirme modundaysanız değişiklik algılama iki kez çalışır (TTL = 2). Bunun hakkında daha fazla bilgi için ApplicationRef.tick () öğesine bakın .) Bu değişiklik dedektörü nesnelerini kullanarak tüm bağlantılarınızda kirli denetim gerçekleştirir.
ngOnChanges()
değişikliklerden haberdar olmak için uygulayabilirsiniz . ngDoCheck()
( daha fazla bilgi için bu SO yanıtına bakın) bu). Daha fazla bilgi için diğer referanslar:
onPush
.host
belgesindeki "Ana Bilgisayar Dinleyicileri" belgelerine bakın . Açısal bölgenin içinden küresel olayların nasıl dinleneceğini açıklar (böylece değişiklik algılaması istenildiği gibi tetiklenir). Bu cevabın çalışan bir dalma pistonu var.
Bu davranış, artık bileşen yaşam döngüsünün bir parçasıdır.
Bir bileşen, giriş değişikliklerine erişmek için OnChanges arabiriminde ngOnChanges yöntemini uygulayabilir .
Misal:
import {Component, Input, OnChanges} from 'angular2/core';
@Component({
selector: 'hero-comp',
templateUrl: 'app/components/hero-comp/hero-comp.html',
styleUrls: ['app/components/hero-comp/hero-comp.css'],
providers: [],
directives: [],
pipes: [],
inputs:['hero', 'real']
})
export class HeroComp implements OnChanges{
@Input() hero:Hero;
@Input() real:string;
constructor() {
}
ngOnChanges(changes) {
console.log(changes);
}
}
Otomatik iki yönlü ciltlemeye ek olarak, bir değer değiştiğinde bir işlevi çağırmak istiyorsanız, iki yönlü ciltleme kısayol sözdizimini daha ayrıntılı sürüme bölebilirsiniz.
<input [(ngModel)]="yourVar"></input>
için kestirme
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(bkz. http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Böyle bir şey yapabilirsiniz:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
Açısal 2'de saat olarak hareket etmek için getter function
veya tuşunu kullanabilirsiniz get accessor
.
Demoyu buradan görebilirsiniz .
import {Component} from 'angular2/core';
@Component({
// Declare the tag name in index.html to where the component attaches
selector: 'hello-world',
// Location of the template for this component
template: `
<button (click)="OnPushArray1()">Push 1</button>
<div>
I'm array 1 {{ array1 | json }}
</div>
<button (click)="OnPushArray2()">Push 2</button>
<div>
I'm array 2 {{ array2 | json }}
</div>
I'm concatenated {{ concatenatedArray | json }}
<div>
I'm length of two arrays {{ arrayLength | json }}
</div>`
})
export class HelloWorld {
array1: any[] = [];
array2: any[] = [];
get concatenatedArray(): any[] {
return this.array1.concat(this.array2);
}
get arrayLength(): number {
return this.concatenatedArray.length;
}
OnPushArray1() {
this.array1.push(this.array1.length);
}
OnPushArray2() {
this.array2.push(this.array2.length);
}
}
İşte model için alıcı ve ayarlayıcı işlevlerini kullanan başka bir yaklaşım.
@Component({
selector: 'input-language',
template: `
…
<input
type="text"
placeholder="Language"
[(ngModel)]="query"
/>
`,
})
export class InputLanguageComponent {
set query(value) {
this._query = value;
console.log('query set to :', value)
}
get query() {
return this._query;
}
}
(change)
Bunların her birine işleyici eklemek istemiyorum ; Modelimdeki get|sets
her mülke s eklemek istemiyorum ; Bir eklemek için yardımcı olmaz get|set
için this.object
; ngOnChanges()
Yalnızca değişiklikleri algılar @Input
s . Kutsal manna! Bize ne yaptılar ??? Bize bir tür derin gözlem verin!
Bunu 2 yönlü bağlama yapmak istiyorsanız, kullanabilirsiniz [(yourVar)]
, ancak yourVarChange
olayı uygulamanız ve değişken değişikliğiniz her seferinde çağırmanız gerekir.
Kahraman değişimini izlemek için böyle bir şey
@Output() heroChange = new EventEmitter();
ve sonra kahramanınız değiştiğinde, this.heroChange.emit(this.hero);
[(hero)]
sizin için dinlenme yapacak bağlama
buradaki örneğe bakın:
Başvurunuz bu deneyin hala talepleri $parse
, $eval
, $watch
açısal davranış gibi
Bu doğrudan soruyu cevaplamıyor, ama ben angularJs $ watch için kullanacağım bir şeyi çözmek için bu Stack Overflow sorusuna indi farklı durumlarda var. Son olarak, mevcut cevaplarda açıklanandan başka bir yaklaşım kullandım ve birisinin yararlı bulması durumunda bunu paylaşmak istiyorum.
Benzer bir şey başarmak için kullandıkları tekniği $watch
bir kullanmaktır BehaviorSubject
( burada konu hakkında daha fazla bir Açısal hizmetinde) ve benim bileşenleri değişiklikleri (izlemek) almak için abone izin verin. Bu, $watch
açısalJ'lere benzer , ancak biraz daha kurulum ve anlayış gerektirir.
Bileşenimde:
export class HelloComponent {
name: string;
// inject our service, which holds the object we want to watch.
constructor(private helloService: HelloService){
// Here I am "watching" for changes by subscribing
this.helloService.getGreeting().subscribe( greeting => {
this.name = greeting.value;
});
}
}
Hizmetimde
export class HelloService {
private helloSubject = new BehaviorSubject<{value: string}>({value: 'hello'});
constructor(){}
// similar to using $watch, in order to get updates of our object
getGreeting(): Observable<{value:string}> {
return this.helloSubject;
}
// Each time this method is called, each subscriber will receive the updated greeting.
setGreeting(greeting: string) {
this.helloSubject.next({value: greeting});
}
}
İşte Stackblitz hakkında bir demo