我有一个显示清单的控制器,并将选择存储在一个数组中。
我的另一个控制器在第一个控制器的阵列上运行$http.get
。
如何设置$watch
以便每当数组发生更改时,都会发送新的HTTP GET请求?
我的尝试: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'];
答案 0 :(得分:3)
默认情况下,$watch
检查引用的更改,而不是相等。由于对象和数组在修改时仍具有相同的引用,因此不会触发监视。至少有两种方法可以让它发挥作用。
如果您想要通知的唯一更改是修改数组的大小(添加或删除元素而不是更改元素的内容),则可以在数组的length属性上设置监视,如:< / p>
$scope.$watch('foo_list_selection.length', function (newValue, oldValue) {
// ...
否则,您可以使用可选的$watch
参数objectEquality
,它需要一个布尔值。这会进行相等检查而不是参考检查。
$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
这不是默认行为,因为它对所有元素执行更昂贵的深度检查,因此仅在必要时使用。
答案 1 :(得分:1)
将部分逻辑移至工厂,然后将其发送给所有带$rootScope.$broadcast
的控制器,将您的信息传送到正确的位置。
我将数组创建移动到工厂,然后使用$ broadcast:
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}
})
在控制器中使用$scope.$on
会在更改时收到新数据:
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
})
}
答案 2 :(得分:0)
在这种情况下,我建议使用服务进行数据操作和消息,以使控制器和UI保持同步。