Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
268 views
in Technique[技术] by (71.8m points)

javascript - scope.$watch in a directive isn't being called after AJAX request

I have the following directive:

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

Here's how I invoke it:

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

When the directive is first initalized, the someField is empty. Later on, it is retrieved via ajax, and its value is filled in.

Question is, how can I watch for the value of someField to be updated? When I do this from the link method:

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

This is only called once, when initalizing the directive, and the value then is empty. When the value is retrieved via ajax (from $http.get), this watch function is not called again. However, in other parts of the page where I'm displaying {{someField}}, that value DOES update when ajax request is fetched. So I don't think the problem has to do with doing $scope.apply() after ajax request.

Edit: someField is assigned in the controller. Here is the 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);               
}
]);

The method ajax.getUser() does a $http.get() and returns its promise. In the code above, the load method is called which sets the value of someField.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

$watch expects an expression that can be either a function or a string. So, it'll work if you change it to

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

or

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

Check out this jsFiddle.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...