在Angular中,当service变量被更新时,Watch不会被触发
Watch not triggered when service variable is updated in Angular
基本上,我正在做的是使用ng-repeat
在视图中加载数据。当发生拖放操作时,我使用指令将项目从一个组移动到另一个组。该指令调用服务中的move函数并更新list变量。
我的问题是,当项目被移动时,ng-repeat
没有更新。我尝试使用$scope.$watch
,但没有运气。服务列表变量正在更新,但是由于某种原因没有触发监视。我尝试使用broadcast
,这是有效的,但我已经读到,这是一个坏的做法,在控制器中使用广播,因为它会产生错误。
更新ng-repeat
的最佳方法是什么?不知道为什么它不起作用。如果您需要更多的细节,请告诉我。
这是我的服务
angular.module('Data', [])
.factory('DataService', DataService);
function DataService() {
var list = [];
list.push({
id: 6,
title: "First Group",
items: [
{
id: 1,
title: "This is an item"
}
]
});
list.push({
id: 7,
title: "Testng",
items: [
]
});
return {
'get': get,
'move': move,
};
function get() {
return list;
}
function move(index, fromItemIndex, toItemIndex) {
list[fromItemIndex].items.push({
id: 5,
title: "This is an item"
});
}
}
这是我的控制器
function MyController($scope, DataService) {
var vm = this;
vm.list = DataService.get();
$scope.$watch(function() {
return DataService.get();
}, function(value) {
console.log('Wtatching');
console.log(value);
}, true);
}
我的观点
<div ng-repeat="item in vm.list track by $index">
<div class="group" droppable group="<% $index %>">
<div class="group-title">
<% group.title %>
</div>
<div class="group-content">
<div ng-repeat="item in item.items track by $index">
<div class="group-item">
<div class="group-item-title"
draggable
group="<% $parent.$index %>"
item="<% $index %>">
<% item.title %>
</div>
</div>
</div>
</div>
</div>
</div>
编辑
这是一个plnker版本:https://plnkr.co/edit/bQuotNU7oOm92PCgmhcj
当您拖拽item 1并将其放到自身上时,您将看到服务列表更新了,但是手表没有被触发。
我认为问题是你的ng-repeat
表达式。试着移除track by $index
.
如果你正在使用jQuery(或其他非angular回调)来移动项目(拖放),那么你需要像这样包装你的move
代码:
function move(index, fromItemIndex, toItemIndex) {
$timeout(function() {
list[fromItemIndex].items.push({
id: 5,
title: "This is an item"
});
});
}
确保在工厂中注入$timeout
。在Angular中有一个文摘循环的概念,Angular会定期更新Angular上下文中的数据。
From the docs:
在$digest阶段,作用域检查所有的$watch表达式并将它们与之前的值进行比较。这个肮脏的检查完成了异步.
如果一些Angular数据在非Angular环境中被修改,比如jQuery拖拽&drop时,Angular将不会意识到这个变化,直到你告诉它。所以使用$scope.$apply()
是用来告诉Angular有些东西发生了变化。但是如果消化循环已经在进行,$apply()
有时会失败,所以建议使用一些Angular的打包服务,比如$timeout
。
要点:
$timeout
用于隐式触发摘要循环
更多细节在这里:https://docs.angularjs.org/error/$rootScope/inprog#triggering-events-programmatically
(考虑使用UI。如果你使用的是基于jQuery的库,则由Angular UI团队维护。
- 在控制器上使用“$watch”时,为什么不更新此隐藏字段
- AngularJS ng src不会在$rootScope上使用$watch进行更新
- 使用$watch更新数据,ng重复不反映更改
- 当数据在另一个URL上更新时,AngularJS是否可以在一个URL上触发$watch
- Angular$watch未更新绑定
- 事件发射器与在 AngularJs 中更新大型数据集时的$watch
- AngularJS:$scope.$watch 不会更新从自定义指令$resource获取的值
- 为什么模型更改时$watch不更新
- AngularJS暂停$watch以进行内部更新
- $watch无法识别更新的属性
- 在 $scope.$watch 中更新时,独立作用域绑定不起作用
- 只更新已使用Webpack.watch()更改的区块
- 在指令中使用$watch的单个值对范围进行角度更新
- angularJS$watch在使用控制器更新数据时不在指令中工作
- $watch未在函数外更新数组
- Angular $watch数组并从服务器更新
- Gulp.watch()不能用于FTP更新
- $watch()没有更新$scope
- 美元的范围.当从指令中添加值时,数组上的$watch不会更新
- $watch仅在window.innerWidth的第一次更新时触发