AngularJS : $scope.$watch is not updating value fetched from $resource on custom directive

╄→尐↘猪︶ㄣ 提交于 2019-11-28 17:16:31

The issue is that watch compares the reference instead of the object by default. Add ,true to the end to have it compare the value instead.

scope.$watch('seats', function(newval, oldval){
                console.log(newval, oldval);
                updateSeatInfo(scope,element);
            }, true);

I had this problem too. It was due to the fact that my variable was at first not defined 'undefined' in the scope. Watch seems to not work on undefined variables. Seems obvious after-all.

I was first trying to use watch to trigger when my variable would be effectively set by the controller. Example:

myApp.controller('Tree', function($scope, Tree) {

Tree.get({},
function(data) { // SUCCESS
    console.log("call api Tree.get succeed");
    $scope.treeData = data;
},

function(data) { // FAILURE
    console.log("call api Tree.get failed");
    $scope.treeData = {};
});
});

I solved it by initializing my variable with an empty object before calling the service:

myApp.controller('Tree', function($scope, Tree) {

$scope.treeData = {};      // HERE

Tree.get({},
function(data) { // SUCCESS
    console.log("call api Tree.get succeed");
    $scope.treeData = data;
},

function(data) { // FAILURE
    console.log("call api Tree.get failed");
    $scope.treeData = {};
});
});

In that case watch was able to detect the change in the variable.

I can't see that you're using the SeatsCtrl-controller anywhere? How is it being used? And have you verified that it is activated, and that the query is actually performed?

The quickest way to check if SeatsCtrl is in use is to simply add a console.log('SeatsCtrl actived!'); inside it. If it is not, then add ng-controller="SeatsCtrl" to the div.

You can also put a watch-and-log on the seats directly inside the controller just to make sure it is not an issue with scoping.

I have this problem too. I think it's a problem in Angular. There is a ticket on GitHub to "beef up $resource futures" which would probably address this issue, as what you really need is access to the promise object for the resource you have.

Or, the watchers could wait to fire until the promise is resolved.

In the meantime, a slightly more elegant way to fix this which doesn't require a timeout is to reassign the scope property that is being watched from the success callback on the $resource. This will cause the watcher to fire again at the appropriate time.

A timeout with no delay is just putting the evaluation of the deferred function on the end of the current stack - in your case, your resource happened to be resolved by then, but this could be a problem if the server is having a case of the Mondays.

Example:

$scope.myAttr = MyResource.fetch(
  function (resource) { $scope.myAttr = new MyResource(angular.copy(resource)); }
);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!