Javascript 通过应用程序保持对象同步的角度
这是一个有角度的问题,也是一个javascript问题 我在angular应用程序中有很多来自后端的对象需要保持最新。我在设置好数据绑定以通过我的应用程序同步时遇到问题 我创建了一个DataService服务,它通过websocket连接到我们的后端。根据需要获取数据并将其本地缓存在名为Javascript 通过应用程序保持对象同步的角度,javascript,angularjs,reference,Javascript,Angularjs,Reference,这是一个有角度的问题,也是一个javascript问题 我在angular应用程序中有很多来自后端的对象需要保持最新。我在设置好数据绑定以通过我的应用程序同步时遇到问题 我创建了一个DataService服务,它通过websocket连接到我们的后端。根据需要获取数据并将其本地缓存在名为store的对象中。例如: 当控制器需要用户列表时,它将查询数据服务,如下所示: DataService.get(users, {}).then( /* function to set something o
store
的对象中。例如:
当控制器需要用户列表时,它将查询数据服务,如下所示:
DataService.get(users, {}).then(
/* function to set something on the scope */
)
// (or as a resolve)
数据服务将从后端获取用户,a)将用户本地缓存到存储对象中,b)返回一个包含结果的数组
当另一个控制器需要相同的数据时,我们只返回缓存
这非常有效,除非数据发生变化,并且后端将其告知数据服务。数据服务可以更新其本地存储缓存,但控制器不知道这些更改。厄运场景示例:
- 当控制器需要完整的用户列表时,并且在一段时间后添加了新用户(在angular环境之外;通过后端),DataService如何更新先前返回的阵列
- 管制员可以请求特定的用户子集(例如来自城市a的所有用户)。当一个来自城市a的新用户进入系统时,数据服务如何知道这是控制器在一段时间前感兴趣的事情?如果DataService存储所有查询,它需要一种将新用户(例如)匹配到这些查询的方法
// js
scope.myThing = $resource('thing_url').get();
// html
{{ myThing.myProperty }}
这是通过利用Angular的摘要循环来实现的。当返回资源时,模板“神奇地”工作。这实际上是因为$resource
服务在完成其请求时会启动一个摘要周期,绑定现在显示正确的信息。您可以对观察者执行相同的操作:
scope.$watch('myThing.myProperty', function (newValue) { /... });
您可以做类似的事情:创建一个服务,返回一个包含服务器结果的对象。假设您可以连接到web套接字层上的事件,则可以在数据更新时启动摘要周期。这样,控制器和模板将被更新
问题作者补充: 在服务中启动摘要循环只是工作的一半。另一半是确保不覆盖对对象(单个模型)和数组(模型集合)的引用。你可以做到这一点 我们的工作解决方案的伪代码:
- 在API服务内创建存储对象(用作所有数据库数据的缓存)
- 每当控制器需要某些信息时,它就会查询API服务
- API服务从后端请求该数据,并将其本地存储在store对象中
- 除了store对象之外,我们还创建了一个最小查询解析器,能够以与后端过滤器相同的方式过滤store对象(我们有一个mongo风格的查询API,其中查询是像
或{city:{amsterdam}
){city:{city!“:“amsterdam”}}
- 对本地存储运行查询,保存查询和结果,并将其传回请求者(指令或控制器)
- 每当模型更新时,重新运行所有可能关联的查询。如果结果发生更改,请使用
更改对象/数组而不丢失引用。在此之后,启动摘要循环,以便控制器了解数据中的更改copy.angular
angular.复制
管制员可以请求特定的用户子集(例如来自城市a的所有用户)。当一个来自城市a的新用户进入系统时,数据服务如何知道这是控制器在一段时间前感兴趣的事情?如果DataService存储所有查询,它需要一种将新用户(例如)匹配到这些查询的方法
只要基础数据发生更改,服务将自动重新运行所有查询。通过这种方式,该服务将使整个angularland的所有数据保持最新。有两种方法。两者都要求您将
$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
});
谢谢,我一定会试试这个。但这仍然意味着在该服务中,我需要存储特定的请求(如doom scenario 2:来自城市A的用户),以及当模型更改时(来自城市A的新用户),该服务可以确定是否应该包括该用户。对吗?问题是我们的应用程序有很多不同的控制器,目前大约有30个,但这将增加(也有大约15个指令,其中一些指令动态加载数据)。第一种方法需要在rootScope中添加我们需要动态加载的所有内容的属性?我将尝试第二种方法:当某些东西发生变化时,每个控制器都可以确定它是否是他感兴趣的东西。这意味着每个控制器中都有大量样板代码。。