Ikatan dua arah sudut, sedikit lebih pengertian

Dari penerjemah
Dari seorang penerjemah : dua tahun lalu saya memulai proyek pertama saya tentang Angular (2+), memiliki latar belakang AngularJS yang besar dan sukses. Transisi tersebut membutuhkan format pemikiran yang nyata, karena terlalu banyak pada A1 dan A2 + dilakukan "sedikit berbeda". Rasa sakit dari transisi secara nyata mengurangi blog thoughtram bagi saya . Setahun yang lalu, saya mendapat izin untuk menerjemahkan artikel ini "tentang dasar dan mudah dimengerti oleh semua orang." Tapi mereka adalah tangan seperti itu (artikel mereka adalah sekelompok yang belum selesai). Anehnya, artikel tersebut diterjemahkan dengan baik di Google translate. Tetapi beberapa nuansa dalam terjemahan ini hilang, belum lagi gaya penulisnya. Gaya penulis belum sepenuhnya dipertahankan dalam versi saya. Tapi, saya harap, saya berhasil menyampaikan mood dan pemikiran artikel tersebut.

Saya mengerti bahwa Angular bukan topik terpopuler di Habré, tetapi saya berharap terjemahannya akan membantu seseorang, seperti artikel asli yang pernah membantu saya.

Itulah yang menyebabkan efek wow di AngularJS tua yang baik, sehingga "mengikat dua arah." Sihir ini langsung jatuh cinta pada AngularJS, dan memecah semua gagasan tentang pemrograman halaman yang membosankan dan (oh, horor!) Formulir Web. Perubahan pada data langsung ditampilkan di layar dan sebaliknya. Mereka yang sebelumnya mengembangkan aplikasi jQuery dianggap mengikat jatuh ke dalam dongeng. Dan monster berjanggut, menggergaji klien yang gemuk sebelum jQuery, mulai dengan panik menghitung bulan-bulan yang hilang secara bodoh itu.

Dan, lebih dari itu, keajaiban ikatan dua arah tersedia tidak hanya untuk notasi khusus dan komponen tertentu. Kita dapat dengan mudah menggunakannya dalam arahan dan komponen kita sendiri (hanya dengan mengatur parameter konfigurasi).

Di Angular2 +, pembuat meninggalkan pengikatan data dua arah bawaan (kecuali melalui ngModel). Tetapi ini tidak berarti bahwa kita tidak dapat menggunakan pengikatan dua arah dalam arahan kita sendiri ... Hanya saja freebie telah selesai dan sekarang kita perlu melakukan sesuatu sendiri. Dan, lebih disukai, dengan pemahaman tentang cara kerjanya di Angular.

Daftar isi



Penjilidan dua arah singkatnya


Di A2 +, hanya satu arahan tunggal yang menerapkan pengikatan data dua arah: ngModel . Dan pada pandangan pertama, ini adalah sihir yang sama seperti di AngularJS (hanya dalam notasi yang berbeda). Tapi apa yang ada di bawah tenda?

Anehnya, di bawah tenda, semuanya relatif sederhana dan logis: pengikatan dua arah dikurangi menjadi pengikatan properti dan pengikatan acara. Dua ikatan unilateral, bukan satu bilateral? Ok, ayo dua.

Dan segera sebuah contoh:

<input [(ngModel)]="username"> <p>Hello {{username}}!</p> 

Ya, ya, ini adalah demo Angular2 yang indah dan menakjubkan dari 2009. Tidak bercanda, cantik. Saat mengubah bidang, nilai nama pengguna jatuh ke dalam model, dan langsung tercermin dalam pesan selamat datang di formulir.

Tetapi bagaimana cara kerjanya? Ingat bahwa pengikatan dua arah dalam Angular2 adalah pengikatan properti dan pengikatan acara. Dan ya, mereka dapat secara bersamaan tersedia dalam satu arahan. Selain itu, bahkan tanpa ngModel , kita dapat dengan mudah menerapkan pengikatan data dua arah. Misalnya, seperti ini:

 <input [value]="username" (input)="username = $event.target.value"> <p>Hello {{username}}!</p> 

Output {{username}} jelas, tetapi apa yang tertulis di sana dalam input ? Mari kita pahami:

  • [value] = “nama pengguna” - notasi dengan tanda kurung, mengaitkan ekspresi nama pengguna dengan properti nilai
  • (input) = "ekspresi" - sebuah notasi dengan tanda kurung, ekspresi terlampir pada acara input (ya, ada peristiwa seperti itu). Dalam kasus kami:
    • username = $ event.target.value - ungkapan ini akan dieksekusi sebagai respons terhadap acara masukan
    • $ event adalah variabel sintetis dalam peristiwa Angular yang membawa muatan: dalam kasus ini, ia berisi informasi tentang apa yang terjadi dan sekitarnya

Apakah semakin jelas? Kami memperbaikinya.

Kami mengikat properti nama pengguna model Angular ke properti nilai elemen input browser (pengikatan satu arah dari model untuk melihat).

Kami juga mengikat ekspresi ke acara masukan elemen kami. Yang menetapkan nilai $ event.target.value ke properti nama pengguna model.

Apa itu $ event.target.value ? Seperti yang telah disebutkan, $ event penuh dengan berbagai informasi berguna tentang acara tersebut. Dalam kasus ini, ini adalah InputEventObject di mana properti target merujuk ke elemen DOM yang memicu peristiwa (mis. Elemen input kami).

Jadi, semua yang kita lakukan pada dasarnya adalah membaca konten ( nilai ) dari elemen input ( $ event.target ) ketika pengguna memasukkan nilai. Dan ketika kami menetapkan nilai nama pengguna ini, data tampilan akan dikirim ke model.

Itu saja. Ini adalah "ikatan dua arah singkatnya . " Kecantikan

Tapi kapan ngModel ikut bermain? Skenario bekerja dengan elemen input sangat umum dan diminati. Dan untuk beberapa alasan saya ingin memiliki arahan yang menyembunyikan implementasi dan menghemat dari penekanan tombol ekstra.

Memahami ngModel


Jika Anda melihat sumbernya, Anda dapat memastikan bahwa ngModel juga memiliki ikatan ke properti dan acara tersebut. Inilah contoh contoh ngModel kami, tetapi tanpa menggunakan sintaks steno:

 <input [ngModel]="username" (ngModelChange)="username = $event"> <p>Hello {{username}}!</p> 

Hampir semuanya sama. Pengikatan properti [ngModel] menangani pembaruan nilai elemen input. Penjilidan acara (ngModelChange) memberi tahu dunia bahwa perubahan sedang terjadi di DOM.

Dan Anda perhatikan bahwa ekspresi handler hanya menggunakan $ event , bukan $ event.target.value . Apa ada yang salah di sini? Tidak semuanya. Seperti yang dinyatakan di atas, $ event adalah variabel sintetis yang membawa muatan . Keputusan apa yang dianggap berguna diambil oleh Angular. Dengan kata lain, ngModelChange menangani ekstraksi target.value dari $ internal acara dan hanya memberi kita apa yang kita inginkan, tanpa kemasan dan rebana. Secara teknis akurat, ini adalah orang-orang dari DefaultValueAccessor : dialah yang mengekstrak data dan mentransfernya ke objek DOM dasar, meskipun ... Anda tidak bisa memikirkannya).

Last but not least, karena menulis nama pengguna dan ngModel dua kali masih berlebihan, Angular memungkinkan penggunaan sintaks yang disingkat [()] , juga disebut "pisang dalam kotak". Yang mirip dengan contoh sebelumnya, dan mengembalikan kita ke contoh dari awal bagian, tetapi dengan pemahaman tentang implementasi ngModel . Memberikan ikatan dua arah yang sama.

 <input [(ngModel)]="username"> <p>Hello {{username}}!</p> 


Buat ikatan data dua arah Anda sendiri


Sekarang kita cukup tahu untuk membuat binding data dua arah kita sendiri. Yang perlu Anda lakukan hanyalah mengikuti aturan yang sama seperti ngModel , yaitu:

  • Masukkan penjilidan properti (misalnya: [foo] )
  • Bind ke acara dengan nama dan akhiran yang sama Ubah (misalnya: (fooChange) )
  • Pastikan bahwa acara yang mengikat mengurus pengambilan properti (jika perlu)

Perhatikan bahwa membuat pengikatan data dua arah membutuhkan kerja lebih banyak daripada AngularJS? Ini bisa sangat menyebalkan bagi kita ... Jika kita akan mencoba menggunakan ikatan dua arah kita sendiri jika memungkinkan. Dalam kehidupan nyata, Anda harus selalu mempertimbangkan apakah kita memerlukan pengikatan dua arah, dan jika perlu, apakah lebih mudah untuk mengambil keuntungan dari ngModel. Yang terakhir, misalnya, terjadi ketika membuat kontrol formulir kustom .

Tetapi katakanlah kita membuat komponen penghitung khusus (dan tidak ingin menggunakan kontrol formulir khusus).

 @Component({ selector: 'custom-counter', template: ` <button (click)="decrement()">-</button> <span>{{counter}}</span> <button (click)="increment()">+</button> ` }) export class CustomCounterComponent { counterValue = 0; get counter() { return this.counterValue; } set counter(value) { this.counterValue = value; } decrement() { this.counter--; } increment() { this.counter++; } } 

Kami memiliki properti komponen penghitung untuk menampilkan nilai penghitung saat ini. Untuk memberikannya pengikatan dua arah, hal pertama yang harus dilakukan adalah mengubahnya menjadi parameter Input . Untuk ini, dekorator @Input () sangat berguna:

 @Component() export class CustomCounterComponent { counterValue = 0; @Input() get counter() { return this.counterValue; } ... } 

Ini sudah memungkinkan Anda untuk mengikat properti komponen ke konsumen sebagai berikut:

 <custom-counter [counter]="someValue"></custom-counter> 

Sekarang kita perlu mengatur event @Output () dengan nama yang sama ( counter ) dan suffix Change (ternyata counterChange). Kami ingin meningkatkan acara ini setiap kali perubahan counter . Mengapa menambahkan properti @Output () . Dan kami menyelesaikan, dalam beberapa getter, counter setter, di mana kami akan mencegat perubahan nilai dan membuang acara dengan nilai counter saat ini:

 @Component() export class CustomCounterComponent { ... @Output() counterChange = new EventEmitter(); set counter(val) { this.counterValue = val; this.counterChange.emit(this.counterValue); } ... } 

Ini dia! Sekarang kita dapat mengikat ekspresi ke properti ini menggunakan sintaks pengikatan data dua arah:

 <custom-counter [(counter)]="someValue"></custom-counter> <p>counterValue = {{someValue}}</p> 

Lihat demo dan coba!

Sekali lagi, perlu diingat bahwa komponen seperti penghitung kustom paling baik diimplementasikan dengan kontrol formulir kustom, dan manfaatkan ngModel untuk menerapkan pengikatan data dua arah, seperti dijelaskan dalam artikel ini .

Kesimpulan


Angular tidak lagi hadir dengan pengikatan data dua arah bawaan. Sebaliknya, ada API di kotak yang memungkinkan Anda untuk menerapkan ikatan penuh sebagai properti dan acara yang mengikat.

ngModel hadir sebagai direktif pengikatan dua arah bawaan di FormsModule (jangan lupa untuk menambahkannya ke bagian impor pada deklarasi @NgModule : sekitar per). Menautkan melalui ngModel harus lebih disukai saat membuat komponen yang berfungsi sebagai kontrol formulir kustom. Kalau tidak, itu semua tergantung pada imajinasi Anda.

PS dari penerjemah: implementasi yang mengikat dalam A2 + telah menjadi lebih modern. Sekarang, hampir set "bebas" digunakan untuk memantau perubahan dengan "feng shui" (meskipun jelas bahwa mekanisme untuk pemeriksaan kotor tetap, setidaknya untuk komponen pengguna tingkat tinggi). Ini memungkinkan untuk meninggalkan 100.500 pengamat (prosedur memantau perubahan dalam data "mereka"). Yang di A1 suka membuat muatan berbahaya di browser dan membutuhkan tangan langsung yang tidak biasa ketika merencanakan halaman interaktif yang kaya.

Dengan komponen yang dirancang dengan benar, A2 out of the box telah menjadi jauh lebih responsif. Biarkan dengan mengorbankan pekerjaan programmer. Sekarang Anda dapat menempatkan sejumlah besar komponen pada halaman dan jangan khawatir tentang sumber daya prosesor.

Sisi lain dari koin adalah biaya awal dari "proses masuk" di A2 +, yang mempengaruhi popularitas kerangka kerja. Tetapi A1 juga memiliki biaya masuk yang tinggi, hanya saja ia diturunkan ke liga utama. Karena kurangnya pemahaman tentang bagaimana mengatur aplikasi besar, banyak prototipe "lepas landas" pada A1, kemudian "hancur" dan berhubungan dengan Bereaksi dan Vue.

Saya berharap bahwa dengan artikel ini saya akan membantu sedikit menurunkan ambang untuk pintu masuk awal ke A2 +, yang terus diminati (yang saya tahu secara langsung).

Source: https://habr.com/ru/post/id453696/


All Articles