J'essaie de faire regarder angulairement le $viewValue
d'un contrôleur de l'intérieur d'une directive.
violon: http://jsfiddle.net/dkrotts/TfTr5/5/
function foo($scope, $timeout) {
$scope.bar = "Lorem ipsum";
$timeout(function() {
$scope.bar = "Dolor sit amet";
}, 2000);
}
myApp.directive('myDirective', function() {
return {
restrict: 'A',
require: '?ngModel',
link: function (scope, element, attrs, controller) {
scope.$watch(controller.$viewValue, function() {
console.log("Changed to " + controller.$viewValue);
});
}
}
});
En l'état, la fonction $ watch n'intercepte pas le changement de modèle effectué après 2 secondes depuis l'intérieur du contrôleur. Qu'est-ce que je rate?
$watch
accepte le "nom" de la propriété à surveiller dans l'oscilloscope, vous lui demandez de surveiller la valeur. Changez-le pour regarder attrs.ngModel
qui renvoie "bar", vous regardez maintenant scope.bar
. Vous pouvez obtenir la valeur de la même manière ou utiliser scope[attrs.ngModel]
, ce qui revient à dire scope["bar"]
qui, encore une fois, est identique à scope.bar
.
scope.$watch(attrs.ngModel, function(newValue) {
console.log("Changed to " + newValue);
});
Pour clarifier le commentaire de user271996: scope.$eval
est utilisé car vous pouvez passer une notation d'objet dans l'attribut ng-model
. c'est-à-dire ng-model="someObj.someProperty"
qui ne fonctionnera pas car scope["someObj.someProperty"]
n'est pas valide. scope.$eval
est utilisé pour évaluer cette chaîne dans un objet réel de sorte que scope["someObj.someProperty"]
devienne scope.someObj.someProperty
.
Vouloir ajouter: dans 1.2.x, avec la portée isolée, ce qui précède ne fonctionnera pas. http://jsfiddle.net/TfTr5/23/
Une solution de contournement que j'ai trouvée utilisait le fait que $ watch accepte également une fonction, vous pouvez donc accéder à votre contrôleur à l'aide de cette fonction.
scope.$watch(
function(){return controller.$viewValue},
function(newVal, oldVal){
//code
}
)
Violon de travail: http://jsfiddle.net/TfTr5/24/
Si quelqu'un a une alternative, je serais ravi de la recevoir!
Si vous souhaitez lier une valeur dans une portée isolée, vous pouvez le faire de deux manières. La première façon que vous pouvez utiliser même si vous n'avez pas de portée isolée. Voici les moyens:
1) utiliser $attrs.any_attribute
et le lier (défini dans la montre)
2) utilisez la méthode 2-way binding ('=') et définissez-la comme écouteur
si vous voulez plus d'exemples, voici un excellent article
Si vous souhaitez effectuer un rebond sur une valeur de modèle, il convient de mentionner le paramètre de rebond dans ng-model-option:
<input type="text" ng-model-options="{ debounce: 1000 }" ng-model="search"/>
Par exemple: cette surveillance est déclenchée 1000 ms après modification et réinitialisée à de nouvelles modifications.
scope.$watch(attrs.ngModel, function(newValue) { });