Apabila saya melaksanakan ciri di tempat kerja baru-baru ini, saya menghadapi masalah kecil: komponen Angular tidak boleh mendapatkan atribut input @Input Walaupun saya agak biasa dengan masalah ini, adalah perlu cari masalahnya. Ia adalah satu proses, jadi saya akan meringkaskan dan merekodkan isu ini.
[Cadangan tutorial berkaitan: "tutorial sudut"]
Saya perlu memberikan KomponenTetapkan atribut input@Input Nah, mudah untuk mengekod secara langsung.
Kod asal adalah seperti ini:
@Component({ selector: 'my-menu', templateUrl: './main-menu.widget.html' }) export class MyMenuWidget { data: any[]; ... constructor(...) { this._changesSubscription = this._service.changes.pipe( map((data: any[]) => { ... return data; }) ).subscribe((data: any[]) => { this.data = data; }); } ... }
Tambah atribut input:
@Component({ selector: 'my-menu', templateUrl: './main-menu.widget.html' }) export class MyMenuWidget { @Input() isMainMenu: boolean = false; data: any[]; ... constructor(...) { this._changesSubscription = this._service.changes.pipe( map((data: any[]) => { ... return data; }) ).subscribe((data: any[]) => { if (this.isMainMenu) { this.data = data.filter((d: any) => d.ID === 233); } else { this.data = data; } }); } ... }
Gunakannya :
<my-menu [isMainMenu]="mainMenu"></my-menu>
Kemudian saya mendapati bahawa atribut input adalahMenu Utama dalam MyMenuWidget tidak pernah dapat nilainya. Saya menyemaknya dan mendapati bahawa tiada masalah sama sekali, tetapi saya tidak dapat mendapatkan nilainya.
Lihat lebih dekat, ahhhh? ? ? , langganan kepada Boleh Diperhatikan sebenarnya ditulis dalam pembina! ! ! Walaupun menulis cara ini boleh berfungsi seperti biasa dalam beberapa senario dan tidak menjejaskan fungsi kod, cara penulisan ini sangat tidak teratur, menyebabkan masalah seperti kod dalam contoh di atas. Oleh itu, semasa perkembangan normal, tidak digalakkan untuk menulis seperti ini. Jadi apakah cara yang betul untuk menulisnya?
Muat naik kod.
@Component({ selector: 'my-menu', templateUrl: './main-menu.widget.html' }) export class MyMenuWidget { @Input() isMainMenu: boolean = false; data: any[]; ... constructor(...) { ... } ngOnInit() { this._changesSubscription = this._service.changes.pipe( map((data: any[]) => { ... return data; }) ).subscribe((data: any[]) => { if (this.isMainMenu) { this.data = data.filter((d: any) => d.ID === 233); } else { this.data = data; } }); } ... }
Maka persoalannya ialah, mengapa kod yang sama boleh berfungsi seperti biasa apabila diletakkan dalam ngOnInit? Sesetengah orang akan mengatakan bahawa kita hanya perlu meletakkannya dalam ngOnInit, tetapi tidak dalam pembina. Jadi mengapa tidak, perlu difikirkan.
Persoalannya, apakah perbezaan antara pembina Angular dan fungsi ngOnInit?
Perbezaan dalam bahasa:
Mari kita lihat dahulu perbezaan mereka dari perspektif bahasa. ngOnInit hanyalah kaedah pada kelas komponen Strukturnya tidak berbeza daripada kaedah lain pada kelas, kecuali ia mempunyai nama tertentu.
export class MyMenuWidget implements OnInit { ngOnInit() {} }
Tidak mengapa untuk melaksanakannya atau tidak saya masih boleh menulisnya seperti ini, tiada masalah langsung. Tiada penanda eksplisit perlu melaksanakan antara muka ini.
export class MyMenuWidget { ngOnInit() {} }
Beginilah cara menulis ES6 Bagaimana untuk menulis kod di atas dalam ES5?
Pembina adalah berbeza sama sekali daripadanya. Ia akan dipanggil semasa membuat contoh kelas.
export class MyMenuWidget { constructor(){} ngOnInit() {} }
Perbezaan dalam proses permulaan komponen:
Dari perspektif permulaan komponen, perbezaan antara kedua-duanya masih sangat besar. Proses permulaan Angular mempunyai dua peringkat utama:
1 Bina pepohon komponen; 2. Lakukan pengesanan perubahan ; . Pertama Pembina baru akan dipanggil untuk membuat contoh, iaitu untuk memanggil pembina kelas komponen. Semua cangkuk kitar hayat termasuk ngOnInit kemudiannya dipanggil sebagai sebahagian daripada fasa pengesanan perubahan.
Apabila Angular memulakan pengesanan perubahan, pepohon komponen telah dibina dan pembina semua komponen dalam pepohon telah dipanggil. Selain itu, setiap nod templat komponen ditambahkan pada DOM pada ketika ini. Di sini anda mempunyai akses kepada semua data yang anda perlukan untuk memulakan komponen - pembekal DI, DOM, dsb. Mekanisme komunikasi @Input dikendalikan sebagai sebahagian daripada fasa pengesanan perubahan, jadi @Input tidak tersedia dalam pembina.
export class MyMenuWidget { constructor(private _elementRef: ElementRef){ ... } ngOnInit() {} }
Untuk Angular
pembina, ia digunakan terutamanya untuk permulaan dan menyuntik kebergantungan. Pendekatan biasa adalah untuk meletakkan logik sesedikit mungkin ke dalam pembina Kadang-kadang, walaupun anda meletakkan banyak logik, ia tidak menjejaskan fungsi. Untuk
ngOnInit, Angular mencipta DOM komponen, menggunakan pembina untuk menyuntik semua kebergantungan yang diperlukan dan memanggil ngOnInit selepas melengkapkan permulaan Ini adalah tempat yang baik untuk melaksanakan logik permulaan komponen . Ringkasnya
, pembinapembina itu sendiri tiada kaitan dengan Angular dan ngOnInit fungsi cangkuk ini ditakrifkan dalam Angular.
RingkasanUntuk lebih banyak pengetahuan berkaitan pengaturcaraan, sila lawati:
Pengajaran PengaturcaraanAtas ialah kandungan terperinci Rekod masalah pembangunan sudut: Komponen tidak boleh mendapatkan atribut input @Input. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!