Javascript 如果外部应用程序更改了持久模型(服务器数据库),AngularJS能否自动更新视图?
我刚刚开始熟悉AngularJS,但我想构建一个web应用程序,当服务器端数据库发生变化时,该应用程序的视图会自动实时更新(无需刷新) AngularJS能(大部分)自动为我处理这个问题吗?如果是这样,工作的基本机制是什么 例如,您是否以某种方式设置AngularJS定期轮询DB以获取“模型”更改?或者使用某种类似Comet的机制通知AngularJS客户端代码模型已更改Javascript 如果外部应用程序更改了持久模型(服务器数据库),AngularJS能否自动更新视图?,javascript,angularjs,websocket,socket.io,Javascript,Angularjs,Websocket,Socket.io,我刚刚开始熟悉AngularJS,但我想构建一个web应用程序,当服务器端数据库发生变化时,该应用程序的视图会自动实时更新(无需刷新) AngularJS能(大部分)自动为我处理这个问题吗?如果是这样,工作的基本机制是什么 例如,您是否以某种方式设置AngularJS定期轮询DB以获取“模型”更改?或者使用某种类似Comet的机制通知AngularJS客户端代码模型已更改 在我的应用程序中,挑战在于其他(非web)服务器端软件有时会更新数据库。但这个问题同样适用于纯web应用程序,在纯web应用
在我的应用程序中,挑战在于其他(非web)服务器端软件有时会更新数据库。但这个问题同样适用于纯web应用程序,在纯web应用程序中,您可能有多个客户端通过AngularJS web客户端更改数据库,并且当其中一个客户端更改数据库(模型)时,每个客户端都需要更新。您有一些选择
$timeout
和$http
每隔X毫秒进行一次轮询,或者如果您使用的数据连接到REST服务,您可以使用$resource
而不是$http
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);
};
}
下面是Angular旧版本中的一个示例,再次使用socket.io:
编辑:对于#3,我一直在使用它来完成此操作。这里有一个使用jetty而不是node的实现。angularjs部分基于AngularSeed应用程序。我不确定angular代码是否是惯用的…但我已经测试过它是否有效。托德 TimerWebSocketServlet请参阅 controllers.js services.js web.xml
TimerServlet
TimerWebSocketServlet
0
TimerServlet
/api/定时器/*
您要找的是和。
Firebase还配备了一个适配器,使使用它变得轻而易举:根据《发现流星》一书,角度手表/示波器与流星关于反应性的计算类似。。。但Angular仅限于客户端,其粒度控制不如Meteor
我的印象是,使用Angular可能更适合为现有应用程序添加反应性,而Meteor在整个应用程序中使用时会飙升。但是我还没有使用Angular的实际经验(尽管我已经构建了一些小型Meteor应用程序)。因此,Andy Joslin在他的回答中提到了我的选项中的最佳解决方案,第三个选项,即通过WebSocket或任何其他您正在处理的异步库双向维护状态(例如,这将是用于Chrome扩展和应用程序的Chrome消息API),toddg给出了一个如何实现的示例。然而,在他的示例中,他在AngularJS中实现了一个反模式:服务正在调用控制器。相反,模型应该放在服务中,然后从控制器引用
服务套接字回调将修改服务模型,因为它是从控制器引用的,所以它将更新视图。如果您处理的是可以重新分配的原始数据类型或变量,请小心,这些类型或变量需要控制器上的监视才能正常工作。感谢您的全面回复,并提供了几个选项ns!期待着在我了解更多关于Angular的知识时理解这一点:)-有一个speling错误。修正了它谢谢你一个简单易懂的回复,非常有用。如果需要销毁控制器,你将如何继续解除事件处理程序的绑定?Brian ford有一个很好的方法,可以让你借助$scope的事件系统和清理。使它总体上非常干净。看看socket.forward()这是一个很好的例子。我只是在学习Angular.js,想知道你是否有完整的应用程序和模板等,以学习?我想补充一点,我已经发现Meteor在框架中为你做了所有这些,所以这是我现在首选的解决方案。将来可能会再次查看Angular。Meteor可能仍然太“新鲜”-它很适合玩,但尚未在大型生产中证明自己(安全性/可伸缩性/性能/等等)。身份验证是在一个多月前添加的。看起来不错,但会等的。@jpeskin-Hi。当你问这个问题的时候,我就在你的身边。你最后做了什么?(我想使用角度)。关于MarkCheck。
// -------------------------------------------------------------
// 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'];
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;
}
};
})});
<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>