Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 323
Ali Avatar asked Aug 09 '13 02:08

Ali


1 Answers

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

like image 114
Michael Benford Avatar answered Oct 05 '22 02:10

Michael Benford