39 votes

AngularJS: champ d'application.$regarder dans une directive n'est pas appelé à une requête AJAX

J'ai la directive suivante:

MyApp.directive('myFilter', ['$filter','$rootScope',
function($filter, $rootScope)
{
    var dir = {};
    dir.restrict = 'E';
    dir.templateUrl = 'views/myFilter.html';
    dir.replace = true;
    dir.scope = 
        {
            name: '@',
            model: '=',
        };

    dir.link = function(scope,el,attrs)
    {        
        //stuff here
    }


    return dir; 
}]);

Voici comment je l'invoquer:

<my-filter model="someField" name="abcd" />

Lorsque la directive est d'abord initalized, l' someField est vide. Plus tard, il est récupéré via ajax, et sa valeur est rempli.

La Question est, comment puis-je regarder pour que la valeur de someField à être mis à jour? Quand je fais cela à partir de la méthode de lien:

scope.$watch(scope.model, function()
{
   console.log( "changed, new val: ", scope.model );
}

Ce n'est appelée qu'une fois, quand initalizing la directive, et la valeur est vide. Lorsque la valeur est récupérée via ajax (à partir de $http.get), cette montre fonction n'est pas appelée à nouveau. Cependant, dans d'autres parties de la page où j'affiche {{someField}}, cette valeur N'est mise à jour lors de la requête ajax est récupéré. Donc, je ne pense pas que le problème a à voir avec le fait de $scope.apply() après une requête ajax.

Edit: someField est attribué dans le contrôleur. Voici le code:

MyApp.controller('myCtrl', 
['$scope', '$rootScope', '$routeParams', 
'ajax', '$filter',

function($scope, $rootScope, $routeParams, ajax, $filter)
{
    var userId = parseInt( $routeParams.userId );        
    $scope.loaded = false;
    $scope.someField = ""; //initalize with empty value

    var load = function(data)
    {
        $scope.loaded = true;
        $scope.someField = data.someField;            
    };        

    ajax.getUser(userId).success(load);               
}
]);

La méthode ajax.getUser() un $http.get() et retourne son promise. Dans le code ci-dessus, l' load méthode est appelé, ce qui définit la valeur de someField.

92voto

Michael Benford Points 5222

$watch s'attend à une expression qui peut être soit une fonction ou d'une chaîne. Donc, il va fonctionner que si vous changer de

scope.$watch('model', function() { ... });

ou

scope.$watch(function() { return scope.model; }, function() { ... });

Découvrez ce jsFiddle.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X