Di AngularJS Anda dapat menentukan pengamat untuk mengamati perubahan dalam variabel lingkup menggunakan $watch
fungsi $scope
. Apa yang setara dengan mengawasi perubahan variabel (misalnya, variabel komponen) di Angular?
Di AngularJS Anda dapat menentukan pengamat untuk mengamati perubahan dalam variabel lingkup menggunakan $watch
fungsi $scope
. Apa yang setara dengan mengawasi perubahan variabel (misalnya, variabel komponen) di Angular?
Jawaban:
Di Angular 2, deteksi perubahan otomatis ... $scope.$watch()
dan $scope.$digest()
RIP
Sayangnya, bagian Deteksi Perubahan panduan pengembang belum ditulis (ada pengganti di dekat bagian bawah halaman Tinjauan Arsitektur , di bagian "The Other Stuff").
Inilah pemahaman saya tentang cara kerja deteksi perubahan:
setTimeout()
di dalam komponen kita daripada sesuatu seperti $timeout
... karena setTimeout()
monyet ditambal.ChangeDetectorRef
.) Detektor perubahan ini dibuat saat Angular membuat komponen. Mereka melacak keadaan semua ikatan Anda, untuk pemeriksaan kotor. Ini, dalam arti tertentu, mirip dengan otomatis $watches()
yang akan diatur oleh Angular 1 untuk {{}}
binding template. onPush
strategi deteksi perubahan pada salah satu komponen Anda), setiap komponen di pohon diperiksa sekali (TTL = 1) ... dari atas, dalam urutan kedalaman-pertama. (Ya, jika Anda dalam mode dev, deteksi perubahan berjalan dua kali (TTL = 2). Lihat ApplicationRef.tick () untuk informasi lebih lanjut tentang ini.) Ini melakukan pemeriksaan kotor pada semua binding Anda, menggunakan perubahan objek detektor.
ngOnChanges()
pemberitahuan perubahan. ngDoCheck()
(lihat jawaban SO ini untuk lebih lanjut hal ini). Referensi lain untuk mempelajari lebih lanjut:
onPush
.host
, dokumentasi "Host Listeners" di DirectiveMetadata API doc . Ini menjelaskan cara mendengarkan acara global dari dalam zona Angular (jadi deteksi perubahan akan dipicu seperti yang diinginkan). Jawaban ini memiliki plunker yang berfungsi.
Perilaku ini sekarang merupakan bagian dari siklus hidup komponen.
Sebuah komponen dapat mengimplementasikan metode ngOnChanges di antarmuka OnChanges untuk mendapatkan akses ke perubahan input.
Contoh:
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);
}
}
Jika, selain pengikatan dua arah otomatis, Anda ingin memanggil fungsi saat suatu nilai berubah, Anda bisa memecah sintaks pintasan pengikatan dua arah ke versi yang lebih verbose.
<input [(ngModel)]="yourVar"></input>
adalah singkatan
<input [ngModel]="yourVar" (ngModelChange)="yourVar=$event"></input>
(lihat misalnya http://victorsavkin.com/post/119943127151/angular-2-template-syntax )
Anda dapat melakukan sesuatu seperti ini:
<input [(ngModel)]="yourVar" (ngModelChange)="changedExtraHandler($event)"></input>
Anda dapat menggunakan getter function
atau get accessor
untuk bertindak sebagai menonton di sudut 2.
Lihat demo di sini .
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);
}
}
Berikut adalah pendekatan lain menggunakan fungsi pengambil dan penyetel untuk model.
@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)
handler (s) pada masing-masing dari mereka; Saya tidak ingin menambahkan get|sets
s ke setiap properti dalam model saya; tidak akan membantu menambahkan get|set
untuk this.object
; ngOnChanges()
hanya mendeteksi perubahan @Input
s . Manna suci! Apa yang mereka lakukan pada kita ??? Beri kami semacam pengawasan mendalam!
Jika Anda ingin menjadikannya 2 cara mengikat, Anda dapat menggunakannya [(yourVar)]
, tetapi Anda harus menerapkannyayourVarChange
acara dan menyebutnya setiap kali perubahan variabel Anda.
Sesuatu seperti ini untuk melacak perubahan pahlawan
@Output() heroChange = new EventEmitter();
dan kemudian saat pahlawanmu diganti, teleponlah this.heroChange.emit(this.hero);
itu [(hero)]
mengikat akan melakukan sisanya untuk Anda
lihat contoh di sini:
Coba ini ketika aplikasi Anda masih menuntut $parse
, $eval
, $watch
seperti perilaku di sudut
Ini tidak menjawab pertanyaan secara langsung, tetapi pada kesempatan yang berbeda saya mendarat di pertanyaan Stack Overflow ini untuk menyelesaikan sesuatu yang saya akan gunakan $ watch for in angularJs. Saya akhirnya menggunakan pendekatan lain dari yang dijelaskan dalam jawaban saat ini, dan ingin membaginya jika ada yang merasa berguna.
Teknik yang saya gunakan untuk mencapai sesuatu yang serupa $watch
adalah dengan menggunakan BehaviorSubject
( lebih banyak tentang topik di sini ) dalam layanan Angular, dan membiarkan komponen saya berlangganan untuk mendapatkan (melihat) perubahan. Ini mirip dengan $watch
di angularJs, tetapi membutuhkan lebih banyak pengaturan dan pemahaman.
Dalam komponen saya:
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;
});
}
}
Dalam pelayanan saya
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});
}
}
Ini demo di Stackblitz