Angularjs 角度:适合将视图绑定到服务数据
将视图绑定到服务数据的正确方法是什么我发现$watch是不受欢迎的 我有一个视图,用于呈现来自服务的数组中的项目 服务将定期从服务器刷新其数据Angularjs 角度:适合将视图绑定到服务数据,angularjs,Angularjs,将视图绑定到服务数据的正确方法是什么我发现$watch是不受欢迎的 我有一个视图,用于呈现来自服务的数组中的项目 服务将定期从服务器刷新其数据 $http({...some params...}) .success(function(data) { cache[key] = data; }); 在视图控制器中,数据是公开的: this.items = SomeFactory.cache[key] 视图具有约束力: ng-repeat="item in $ctrl.items" 我
$http({...some params...})
.success(function(data) {
cache[key] = data;
});
在视图控制器中,数据是公开的:
this.items = SomeFactory.cache[key]
视图具有约束力:
ng-repeat="item in $ctrl.items"
我的理解是,由于cache[key]
被分配给一个新数组,因此视图仍然绑定到旧地址,因此没有更新
做这件事的正确方法是什么?
如果我使用一个函数(例如:
ng repeat=“item in$ctrl.items()”
)绑定它,它确实可以工作,但我如何修改该项?从性能角度看,我不知道这是否比直接绑定效率低?有几种方法可以做到这一点,我以前已经非常成功地使用过:
选项1-单向“向上”绑定
假设我们有相同的工厂结构:
angular.module('someApp').factory('SomeFactory', function($http) {
var cache = {};
$http({...some params...})
.success(function(data) {
// ...
cache[key] = data;
});
return {
cache: cache
};
});
我们可以绑定到工厂本身,而不是直接将项设置为缓存[key]
。毕竟,工厂(或服务)只是一个对象:
this.cache = SomeFactory.cache // bind to container which is going to persist
然后在模板中使用ng repeat=“item in$ctrl.cache[key]”
,它将自动获得最新的更改。您甚至可以执行额外的步骤,直接将服务绑定到作用域,如this.SomeFactory=SomeFactory
,然后在视图中使用它作为$ctrl.SomeFactory.cache[key]
。它适用于每个应用程序加载一次的数据结构,或者专门为特定控制器制作的服务
这种方法存在一个潜在的问题,这取决于您如何使用它。您提到修改数组,但由于我们异步重写引用,因此可能很难确保这些更改保持不变
选项2-修改阵列,而不是替换阵列
解决这个问题的另一种方法是稍微修改一下我们的工厂:
angular.module('someApp').factory('SomeFactory', function($http) {
var cache = {};
cache[key] = []; // initialise an array which we'll use everywhere
$http({...some params...})
.success(function(data) {
// ...
cache[key].push.apply(cache[key], data); // essentially a pushAll
// we could also set cache[key].length = 0 to clear previous data or do something else entirely
});
return {
cache: cache
};
});
如您所见,我们没有替换引用,而是在items
属性引用的同一数组上操作。这里的好处是,如果我们以任何方式操作数组(即添加额外的项),那么在接收到新的异步数据后,我们可以更灵活地处理它们
这实际上类似于ngResource使用的方法—收集查询方法返回一个数组,该数组在实际获取数据之后填充
选项3-公开承诺
我之前使用的最后一种方法是公开数据的承诺:
angular.module('someApp').factory('SomeFactory', function($http) {
var cache = {};
var whenReady = $http({...some params...})
.then(function(data) {
// ...
cache[key] = data;
return data;
});
return {
cache: cache,
whenReady: whenReady
};
});
然后,在控制器中,您只需在其解析后分配它:
SomeFactory.whenReady.then(items => {
this.items = items; // or this.items = SomeFactory.cache[key];
});
所有这些都避免了额外的$watch
,但这取决于什么对你的应用程序最方便。Hmmm,你确定它不会更新吗?我已经创造了一个似乎是这样工作的。还有什么其他原因可能会导致这个问题吗?嗯,很有意思。我会再试试的。也许是两层物体引起的不,你说得对,我是个哑巴。您使用它的方式与plunker有点不同。我会写一个关于我们如何处理类似用例的答案。谢谢你的回答。至于选项#2,基本上复制所有元素的性能影响是什么?我们不是复制元素,我们基本上是调用cache[key]。在循环中推送,所以我们甚至没有创建新数组。就性能影响而言,最好的方法是分析——这很可能无关紧要,除非你经常这样做。我会说,选择哪个解决方案是最可维护的,然后在分析之后决定是否存在问题。