Bagaimana cara berlangganan perubahan properti saat menggunakan controller as
sintaks?
controller('TestCtrl', function ($scope) {
this.name = 'Max';
this.changeName = function () {
this.name = new Date();
}
// not working
$scope.$watch("name",function(value){
console.log(value)
});
});
<div ng-controller="TestCtrl as test">
<input type="text" ng-model="test.name" />
<a ng-click="test.changeName()" href="#">Change Name</a>
</div>
Jawaban:
Ikat saja konteks yang relevan.
Contoh: http://jsbin.com/yinadoce/1/edit
MEMPERBARUI:
Jawaban Bogdan Gersak sebenarnya setara, kedua jawaban itu mencoba mengikat
this
dengan konteks yang benar. Namun, saya menemukan jawabannya lebih bersih.Setelah mengatakan itu, pertama dan terutama, Anda harus memahami ide yang mendasarinya .
PEMBARUAN 2:
Bagi mereka yang menggunakan ES6, dengan menggunakan
arrow function
Anda mendapatkan fungsi dengan konteks yang tepat OOTB.Contoh
sumber
$scope
untuk Anda adalah jenis layanan yang memasok metode semacam ini.name
dalamreturn this.name;
mengacu pada nama kontroler atau properti "name
" di sini?angular.bind
mengembalikan fungsi dengan konteks terbatas (arg # 1). Dalam kasus kami, kami mengikatthis
, yang merupakan instance dari controller, ke fungsi (arg # 2), jadithis.name
berarti propertiname
instance dari controller.Saya biasanya melakukan ini:
sumber
$scope.$watch
dan menggunakan fungsi itu untuk mengembalikan nilai dari penutupan. Saya belum menemukan contoh lain dari ini, tetapi ini berhasil dan merupakan yang terbaik. Alasan saya tidak memilih jawaban di bawah ini (yaitu,$scope.$watch('test.name', function (value) {});
) adalah karena diperlukan bahwa saya membuat hard-code apa yang saya beri nama controller saya di template saya atau di $ stateProvider ui.router dan setiap perubahan di sana secara tidak sengaja akan merusak pengamat.angular.bind
) adalah apakah Anda ingin mengikatthis
atau hanya menambahkan referensi lain kethis
dalam penutupan. Ini secara fungsional setara, dan, dalam pengalaman saya, pilihan semacam ini sering kali merupakan panggilan subjektif dan masalah pendapat yang sangat kuat.$scope.$watch( ()=> { return this.name' }, function(){} )
Panah gemuk untuk menyelamatkan() => this.name
$scope.$watchCollection
dan masih mendapatkanoldVal, newVal
params?Kamu bisa memakai:
Ini berfungsi JSFiddle dengan contoh Anda.
sumber
Mirip dengan menggunakan "tes" dari "TestCtrl sebagai tes", seperti yang dijelaskan dalam jawaban lain, Anda dapat menetapkan "diri" lingkup Anda:
Dengan cara ini, Anda tidak terikat dengan nama yang ditentukan dalam DOM ("TestCtrl as test") dan Anda juga menghindari keharusan .bind (this) ke suatu fungsi.
... untuk digunakan dengan html asli yang ditentukan:
sumber
$scope
layanan, jadi Jika kita tambahkan$scope.self = this
, maka di pengontrol lain jika kita melakukan hal yang sama, Apa yang akan terjadi di sana?AngularJs 1.5 mendukung $ ctrl default untuk struktur ControllerAs.
sumber
Anda benar-benar dapat meneruskan fungsi sebagai argumen pertama dari $ watch ():
Yang berarti kami dapat mengembalikan referensi this.name kami:
Baca posting menarik tentang topik controllerAs https://toddmotto.com/digging-into-angulars-controller-as-syntax/
sumber
Anda dapat menggunakan siklus hidup komponen sudut $ onChanges .
lihat dokumentasi di sini: https://docs.angularjs.org/guide/component di bawah bagian aplikasi berbasis Komponen
sumber
Menulis $ arloji dalam sintaks ES6 tidak semudah yang saya harapkan. Inilah yang dapat Anda lakukan:
sumber
CATATAN : Ini tidak berfungsi ketika View dan Controller digabungkan dalam rute atau melalui objek definisi direktif. Apa yang ditampilkan di bawah ini hanya berfungsi ketika ada "SomeController sebagai SomeCtrl" di HTML. Seperti Mark V. tunjukkan dalam komentar di bawah, dan seperti yang dia katakan lebih baik dilakukan seperti yang dilakukan Bogdan.
Saya menggunakan:
var vm = this;
di awal controller untuk mendapatkan kata "ini" keluar dari jalan saya. Laluvm.name = 'Max';
dan di arloji sayareturn vm.name
. Saya menggunakan "vm" sama seperti @Bogdan menggunakan "diri". Var ini, baik itu "vm" atau "diri" diperlukan karena kata "ini" mengambil konteks yang berbeda di dalam fungsi. (jadi mengembalikan this.name tidak berfungsi) Dan ya, Anda perlu menyuntikkan $ scope pada solusi "controller as" Anda yang indah untuk mencapai $ watch. Lihat Panduan Gaya John Papa: https://github.com/johnpapa/angularjs-styleguide#controllerssumber
Inilah cara Anda melakukan ini tanpa $ scope (dan $ watch!) Top 5 Kesalahan - Menonton yang menyalahgunakan
Jika Anda menggunakan sintaks "controller as", lebih baik dan bersih untuk menghindari penggunaan $ scope.
Ini kode saya di JSFiddle . (Saya menggunakan layanan untuk menyimpan nama, jika ES5 Object.defineProperty mengatur dan mendapatkan metode menyebabkan panggilan tak terbatas.
sumber