Tunggu sampai angular mengevaluasi variabel
Saya telah banyak mengotak-atik ini, dan tidak bisa membuatnya bekerja bahkan dengan variabel yang ditentukan "="
dalam ruang lingkup. Berikut tiga solusi tergantung pada situasi Anda.
Solusi # 1
Saya menemukan bahwa variabel belum dievaluasi oleh angular ketika diteruskan ke direktif. Ini berarti Anda dapat mengakses dan menggunakannya di template, tetapi tidak di dalam link atau fungsi pengontrol aplikasi kecuali kita menunggu untuk dievaluasi.
Jika variabel Anda berubah , atau diambil melalui permintaan, Anda harus menggunakan $observe
atau $watch
:
app.directive('yourDirective', function () {
return {
restrict: 'A',
// NB: no isolated scope!!
link: function (scope, element, attrs) {
// observe changes in attribute - could also be scope.$watch
attrs.$observe('yourDirective', function (value) {
if (value) {
console.log(value);
// pass value to app controller
scope.variable = value;
}
});
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: ['$scope', '$element', '$attrs',
function ($scope, $element, $attrs) {
// observe changes in attribute - could also be scope.$watch
$attrs.$observe('yourDirective', function (value) {
if (value) {
console.log(value);
// pass value to app controller
$scope.variable = value;
}
});
}
]
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$watch('variable', function (value) {
if (value) {
console.log(value);
}
});
}]);
Dan inilah htmlnya (ingat tanda kurung!):
<div ng-controller="MyCtrl">
<div your-directive="{{ someObject.someVariable }}"></div>
<!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Perhatikan bahwa Anda tidak boleh menyetel variabel ke "="
dalam cakupan, jika Anda menggunakan $observe
fungsi tersebut. Juga, saya menemukan bahwa ia melewatkan objek sebagai string, jadi jika Anda mengirimkan objek gunakan solusi # 2 atau scope.$watch(attrs.yourDirective, fn)
(, atau # 3 jika variabel Anda tidak berubah).
Solusi # 2
Jika variabel Anda dibuat di misalnya pengontrol lain , tetapi hanya perlu menunggu sampai angular telah mengevaluasinya sebelum mengirimkannya ke pengontrol aplikasi, kita dapat menggunakan $timeout
untuk menunggu hingga $apply
telah dijalankan. Juga kita perlu menggunakan $emit
untuk mengirimkannya ke pengontrol aplikasi lingkup induk (karena lingkup terisolasi dalam direktif):
app.directive('yourDirective', ['$timeout', function ($timeout) {
return {
restrict: 'A',
// NB: isolated scope!!
scope: {
yourDirective: '='
},
link: function (scope, element, attrs) {
// wait until after $apply
$timeout(function(){
console.log(scope.yourDirective);
// use scope.$emit to pass it to controller
scope.$emit('notification', scope.yourDirective);
});
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: [ '$scope', function ($scope) {
// wait until after $apply
$timeout(function(){
console.log($scope.yourDirective);
// use $scope.$emit to pass it to controller
$scope.$emit('notification', scope.yourDirective);
});
}]
};
}])
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$on('notification', function (evt, value) {
console.log(value);
$scope.variable = value;
});
}]);
Dan inilah htmlnya (tanpa tanda kurung!):
<div ng-controller="MyCtrl">
<div your-directive="someObject.someVariable"></div>
<!-- use ng-bind in stead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Solusi # 3
Jika variabel Anda tidak berubah dan Anda perlu mengevaluasinya dalam direktif Anda, Anda dapat menggunakan $eval
fungsi:
app.directive('yourDirective', function () {
return {
restrict: 'A',
// NB: no isolated scope!!
link: function (scope, element, attrs) {
// executes the expression on the current scope returning the result
// and adds it to the scope
scope.variable = scope.$eval(attrs.yourDirective);
console.log(scope.variable);
},
// the variable is available in directive controller,
// and can be fetched as done in link function
controller: ['$scope', '$element', '$attrs',
function ($scope, $element, $attrs) {
// executes the expression on the current scope returning the result
// and adds it to the scope
scope.variable = scope.$eval($attrs.yourDirective);
console.log($scope.variable);
}
]
};
})
.controller('MyCtrl', ['$scope', function ($scope) {
// variable passed to app controller
$scope.$watch('variable', function (value) {
if (value) {
console.log(value);
}
});
}]);
Dan inilah htmlnya (ingat tanda kurung!):
<div ng-controller="MyCtrl">
<div your-directive="{{ someObject.someVariable }}"></div>
<!-- use ng-bind instead of {{ }}, when you can to avoids FOUC -->
<div ng-bind="variable"></div>
</div>
Juga, lihat jawaban ini: https://stackoverflow.com/a/12372494/1008519
Referensi untuk masalah FOUC (flash konten tanpa gaya): http://deansofer.com/posts/view/14/AngularJs-Tips-and-Tricks-UPDATED
Untuk yang tertarik: inilah artikel tentang siklus hidup sudut