如果持久模型(服务器数据库)由外部应用程序更改,AngularJS是否可以自动更新视图?

我刚刚开始熟悉AngularJS,但是我想要构build一个Web应用程序,当服务器端数据库中的某些内容发生变化时,该应用程序将获得实时自动修改(不刷新)的视图。

AngularJS能够为我自动处理(大部分)吗? 如果是这样,工作的基本机制是什么?

例如,你是否设置AngularJS定期轮询数据库“模型”的变化? 或者使用某种类似Comet的机制来通知AngularJS客户端代码模型已经改变?

在我的应用程序中,挑战在于其他(非Web)服务器端软件有时会更新数据库。 但是,这个问题同样适用于纯Web应用程序,您可能会有多个客户端通过AngularJS Web客户端更改数据库,并且当其中一个客户端更改数据库(模型)时,每个客户端都需要更新。

你有几个select…

  1. 您可以使用$timeout$http每X毫秒进行轮询,或者如果您使用的数据连接到REST服务,则可以使用$resource而不是$http

  2. 您可以创build一个使用某个Websocket实现的服务,并使用scope.$apply来处理套接字所推送的更改。 这是一个使用socket.io的例子,一个node.js websocket库:

     myApp.factory('Socket', function($rootScope) { var socket = io.connect('http://localhost:3000'); //Override socket.on to $apply the changes to angular return { on: function(eventName, fn) { socket.on(eventName, function(data) { $rootScope.$apply(function() { fn(data); }); }); }, emit: socket.emit }; }) function MyCtrl($scope, Socket) { Socket.on('content:changed', function(data) { $scope.data = data; }); $scope.submitContent = function() { socket.emit('content:changed', $scope.data); }; } 
  3. 你可以得到真正的高科技,并创build一个websocket实现,使服务器与Angular模型同步。 当客户端改变一些东西时,这个改变会自动发送到服务器。 或者如果服务器发生变化,它会被发送到客户端。
    下面是Angular的一个旧版本的例子,再次使用socket.io:https://github.com/mhevery/angular-node-socketio

编辑 :#3,我一直在使用Firebase来做到这一点。

这是一个使用jetty代替节点的实现。 angularjs部分基于angular-seed应用程序。 我不确定angular码是否是惯用的…但是我testing了这个工作。 HTH – 托德。

TimerWebSocketServlet请参阅

https://gist.github.com/3047812

controllers.js

 // ------------------------------------------------------------- // TimerCtrl // ------------------------------------------------------------- function TimerCtrl($scope, CurrentTime) { $scope.CurrentTime = CurrentTime; $scope.CurrentTime.setOnMessageCB( function (m) { console.log("message invoked in CurrentTimeCB: " + m); console.log(m); $scope.$apply(function(){ $scope.currentTime = m.data; }) }); } TimerCtrl.$inject = ['$scope', 'CurrentTime']; 

services.js

 angular.module('TimerService', [], function ($provide) { $provide.factory('CurrentTime', function () { var onOpenCB, onCloseCB, onMessageCB; var location = "ws://localhost:8888/api/timer" var ws = new WebSocket(location); ws.onopen = function () { if(onOpenCB !== undefined) { onOpenCB(); } }; ws.onclose = function () { if(onCloseCB !== undefined) { onCloseCB(); } }; ws.onmessage = function (m) { console.log(m); onMessageCB(m); }; return{ setOnOpenCB: function(cb){ onOpenCB = cb; }, setOnCloseCB: function(cb){ onCloseCB = cb; }, setOnMessageCB: function(cb){ onMessageCB = cb; } }; })}); 

web.xml中

 <servlet> <servlet-name>TimerServlet</servlet-name> <servlet-class>TimerWebSocketServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet> <servlet-mapping> <servlet-name>TimerServlet</servlet-name> <url-pattern>/api/timer/*</url-pattern> </servlet-mapping> 

你正在寻找的是Firebase和Deployd 。 Firebase附带了一个适配器,使用起来很轻松: http : //angularfire.com/

根据“Discover Meteor”一书,Angular手表/示波器与Meteor的反应计算类似…但是Angular只是客户端,并且比Meteor的粒度控制要小。

我的印象是,使用Angular可能更适合为现有的应用程序添加react native,而meteor使用它的整个事情飙升。 但是我没有Angular的实际经验,但是(虽然我已经build立了一些小meteor应用程序)。

所以,Andy Joslin在他的回答中提到了我最好的解决scheme,第三个选项是通过websockets或任何其他asynchronous库来维护状态(这将是Chrome扩展的Chrome消息API和应用程序)和toddg已经给出了一个如何实现的例子。 但是,在他的例子中,他正在AngularJS中实施反模式:服务正在调用控制器。 相反,模型应放置在服务中,然后从控制器引用。

服务套接字callback将修改服务模型,并且由于它是从控制器引用的,它将更新视图。 小心如果你正在处理原始的数据types或variables,可以重新分配,但这些将需要在控制器上的手表,使这项工作。