web-dev-qa-db-fra.com

Observez la valeur du modèle de contrôleur à partir de la directive inside

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?

22
Dustin

$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.

48
Jonathan Rowny

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!

9
wlingke

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 

http://www.w3docs.com/snippets/angularjs/bind-variable-inside-angularjs-directive-isolated-scope.html

1
Hazarapet Tunanyan

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) { });

https://docs.angularjs.org/api/ng/directive/ngModelOptions

0
Frankey