这是一个角度问题以及一个javascript问题。
我的角应用程序中有很多对象来自后端,需要保持最新状态。我无法通过我的应用程序设置好的数据绑定来同步它。
我创建了一个DataService服务,它通过websocket连接到我们的后端。根据需要获取数据并将其本地缓存在名为store
的对象中。例如:
当控制器需要用户列表时,它将查询DataService,如下所示:
DataService.get(users, {}).then(
/* function to set something on the scope */
)
// (or as a resolve)
DataService将从我们的后端获取用户,a)在本地缓存商店对象中的用户,b)返回包含结果的数组。
当另一个控制器需要相同的数据时,我们只返回缓存。
这很有效,除非数据发生变化且后端告诉DataService有关它。 DataService可以更新其本地存储缓存,但控制器不知道这些更改。示例厄运场景:
答案 0 :(得分:1)
我是Angular核心中$resource服务的忠实粉丝。使用此选项时,从数据返回的属性将分配给$ resource对象实例上的对象。所以
// js
scope.myThing = $resource('thing_url').get();
// html
{{ myThing.myProperty }}
这可以通过利用Angular的摘要周期来实现。返回资源时,模板“神奇地”起作用。这实际上是因为$resource
服务在完成请求时启动了摘要周期,绑定现在显示正确的信息。你可以和观察者做同样的事情:
scope.$watch('myThing.myProperty', function (newValue) { /... });
您可以执行类似的操作:创建一个服务,该服务返回包含服务器结果的对象。假设您可以连接到Web套接字层上的事件,则可以在数据更新时启动摘要周期。这样,控制器和模板将会更新。
问题作者补充:
在服务中踢消化周期只是工作的一半。另一半是确保不覆盖对象(单个模型)和数组(模型集合)的引用。您可以实现此by using angular.copy
when updating the local models inside your service。
我们工作解决方案的伪代码:
{city: "amsterdam"}
或{{1}之类的对象})。{city: {"!": "amsterdam"}}
更改对象/数组而不丢失引用。之后启动摘要周期,以便控制器知道数据的变化。这解决了所有的doomscenarios:
当控制器需要完整的用户列表时,在一段时间后添加新用户(在角度环境之外;通过后端),DataService如何更新先前返回的数组?
copy.angular
控制器可以请求特定的用户子集(例如,来自城市A的所有用户)。当来自城市A的新用户进入系统时,DataService应该如何知道这是控制器感兴趣的东西?如果DataService存储所有查询,则需要一种方法将新用户(例如)与这些查询进行匹配。
每当基础数据发生变化时,服务都会自动重新运行所有查询。这样,该服务将使整个角度范围内的所有数据保持最新。
答案 1 :(得分:0)
有两种方法可以做到这一点。两者都要求您将$rootScope
注入您的服务。
如果你在控制器中使用$scope.users = DataService.users
这样的东西,第一种方法是好的。只需触发所有范围即可更新传入的消息,例如:
$rootScope.$apply(function () {
users.push(newUser);
});
第二种方法是在收到来自服务器的消息时从根作用域广播事件:
$rootScope.$broadcast('server:update', data);
在你的控制器中听它:
$scope.$on('server:update', function (data) {
// Whatever you need to do
});