admin管理员组文章数量:1323035
I have one controller which displays a checklist, and stores the selection in an array.
My other controller runs an $http.get
on the array from the first controller.
How do I set a $watch
so that whenever the array changes, a new HTTP GET request is sent?
My attempt:
// See plnkr for other controller + FooSelection factory + view
function SimpleQueryResCtrl($scope, $http, FooSelection) {
$scope.foo_list_selection = FooSelection;
$scope.$watch('foo_list_selection', function (newValue, oldValue) {
if (newValue !== oldValue)
$http.get('/api/' + $scope.foo_list_selection).success(function (largeLoad) {
$scope.myData = largeLoad;
});
});
}
SimpleQueryResCtrl.$inject = ['$scope', '$http', 'FooSelection'];
I have one controller which displays a checklist, and stores the selection in an array.
My other controller runs an $http.get
on the array from the first controller.
How do I set a $watch
so that whenever the array changes, a new HTTP GET request is sent?
My attempt: http://plnkr.co/edit/EaCbnKrBQdEe4Nhppdfa
// See plnkr for other controller + FooSelection factory + view
function SimpleQueryResCtrl($scope, $http, FooSelection) {
$scope.foo_list_selection = FooSelection;
$scope.$watch('foo_list_selection', function (newValue, oldValue) {
if (newValue !== oldValue)
$http.get('/api/' + $scope.foo_list_selection).success(function (largeLoad) {
$scope.myData = largeLoad;
});
});
}
SimpleQueryResCtrl.$inject = ['$scope', '$http', 'FooSelection'];
Share
Improve this question
edited Apr 5, 2020 at 6:47
Dan
63.2k18 gold badges110 silver badges119 bronze badges
asked Jun 2, 2013 at 13:58
Foo StackFoo Stack
2,3157 gold badges25 silver badges25 bronze badges
9
- I think your code is correct, are you getting errors? You could also check if newValue !== oldValue to make sure your request if fired only when 'foo_list_selection' really changes. – Bertrand Commented Jun 2, 2013 at 14:08
- Okay, I believe this is the simplest runnable example I can make: plnkr. You should see in your console that HTTP requests were made, but none were made from this example. – Foo Stack Commented Jun 2, 2013 at 14:16
- I fixed some errors in your plunker, it seems to be working fine: plnkr.co/edit/nnRw4Pu5x9YQyyqWPc4h?p=preview – joakimbl Commented Jun 2, 2013 at 14:23
- It is working for me, every time I type something in the input a get request if being fired to /api/ + foo_list_selection. – Bertrand Commented Jun 2, 2013 at 14:29
-
Thanks, your sample does work. Unfortunately when I switch from
input
tag to my checkbox tag it fails. – Foo Stack Commented Jun 2, 2013 at 14:53
3 Answers
Reset to default 3By default, a $watch
checks for changes to a reference, not for equality. Since objects and arrays still have the same reference when modified, the watch is not triggered. There are at least two options to get it working.
If the only changes you want to be notified of modify the size of the array (adding or removing elements vs. changing the content of an element), you can set the watch on the length property of the array instead like:
$scope.$watch('foo_list_selection.length', function (newValue, oldValue) {
// ...
Otherwise, you can use the optional $watch
argument objectEquality
, which expects a boolean. This does an equality check rather than a reference check.
$scope.$watch('foo_list_selection', function (newValue, oldValue) {
if (newValue !== oldValue)
$http.get('/api/' + $scope.foo_list_selection).success(function (largeLoad) {
$scope.myData = largeLoad;
});
}, true); // <- put `true` here
This is not the default behavior because it performs a more costly deep check of all the elements so only use when necessary.
Moving some of that logic into the factory, then sending it out to all controllers with a $rootScope.$broadcast
will get your information to the correct places.
I moved the array creation into the factory, then used the $broadcast from there:
myApp.factory('FooSelection', function ($rootScope) {
var tempArr = [];
var fixArray = function(item){
if (tempArr.indexOf(item) === -1){
tempArr.push(item);
} else {
tempArr.splice(tempArr.lastIndexOf(item), 1);
}
$rootScope.$broadcast('newArray', tempArr);
}
return {fixArray: fixArray}
})
Using $scope.$on
in the controllers receives the new data when it changes:
function SimpleQueryResCtrl($scope, $http, FooSelection) {
$scope.foo_list_selection = FooSelection;
$scope.$on('newArray', function(evt, message){
console.log(message) // and you can put your $get method here
})
}
Here's the plunk
In such cases, I remend using a service for data manipulation and messages to keep the controllers and UI in sync.
Take a look here: AngularJS multiple uses of Controller and rootScope
本文标签: javascriptwatch not working on variable from other controllerStack Overflow
版权声明:本文标题:javascript - $watch not working on variable from other controller? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742108032a2421113.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论