javascript - org - ng-if
¿Puede AngularJS actualizar automáticamente una vista si una aplicación externa cambia un modelo persistente(base de datos del servidor)? (5)
Aquí hay una implementación que usa el embarcadero en lugar del nodo. La parte angularjs se basa en la aplicación de semillas angulares. No estoy seguro si el código angular es idiomático ... pero he probado que esto funciona. HTH -Todd.
TimerWebSocketServlet see
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>
Estoy empezando a familiarizarme con AngularJS, pero me gustaría construir una aplicación web que tenga una vista que se active automáticamente en tiempo real (sin actualización) para el usuario cuando algo cambie en la base de datos del servidor.
¿AngularJS puede manejar esto (sobre todo) automáticamente para mí? Y si es así, ¿cuál es el mecanismo básico en funcionamiento?
Por ejemplo, ¿de alguna manera configura AngularJS para sondear el DB regularmente para cambios de "modelo"? ¿O utilizar algún tipo de mecanismo similar a Comet para notificar al código del lado del cliente AngularJS que el modelo ha cambiado?
En mi aplicación, el desafío es que otro software (no web) del lado del servidor actualizará la base de datos a veces. Pero esta pregunta se aplica igualmente a las aplicaciones web puras donde es posible que haya varios clientes que cambien la base de datos a través de los clientes web de AngularJS, y cada uno de ellos debe actualizarse cuando uno de ellos realice un cambio en el DB (modelo).
De acuerdo con el libro "Discover Meteor", los relojes / alcances angulares son similares a los cálculos de Meteor con respecto a la reactividad ... pero Angular es solo para el cliente y proporciona un control menos granular que Meteor.
Mi impresión es que usar Angular podría ser una mejor opción para agregar reactividad a una aplicación existente, mientras que Meteor se dispara cuando lo utilizas para todo. Pero aún no tengo experiencia real con Angular (aunque he desarrollado algunas aplicaciones pequeñas de Meteor).
Lo que estás buscando es Firebase y Deployd . Firebase también viene con un adaptador que hace que usarlo sea muy sencillo: http://angularfire.com/
Por lo tanto, Andy Joslin mencionó la mejor solución en mi opnión en su respuesta, la tercera opción, que es mantener el estado bidireccional a través de websockets o cualquier otra biblioteca asíncrona con la que estés lidiando (esta sería la API de mensaje de Chrome para extensiones de Chrome y Aplicaciones, por ejemplo), y toddg ha dado un ejemplo de cómo se lograría eso. Sin embargo, en su ejemplo, está implementando un antipatrón en AngularJS: el servicio llama al controlador. En cambio, el modelo debe colocarse dentro del servicio y luego debe hacer referencia desde el controlador.
Las devoluciones de llamadas de socket de servicio modificarán el modelo de servicio, y dado que se hace referencia desde el controlador, actualizará la vista. Sin embargo, tenga cuidado si está tratando con tipos de datos primitivos o variables que pueden reasignarse, por lo que necesitará un control en el controlador para que esto funcione.
Tienes algunas opciones ...
Puede hacer sondeos cada X milisegundos usando
$timeout
y$http
, o si los datos que está utilizando están conectados a un servicio REST, puede usar$resource
lugar de$http
.Puede crear un servicio que use alguna implementación de Websocket y use el
scope.$apply
para manejar los cambios que el socket empuja. Aquí hay un ejemplo usando socket.io, una biblioteca websocket node.js: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); }; }
Puede obtener tecnología realmente avanzada y crear una implementación de websocket que sincronice un modelo angular con el servidor. Cuando el cliente cambia algo, ese cambio se envía automáticamente al servidor. O si el servidor cambia, se envía al cliente.
Aquí hay un ejemplo de eso en una versión anterior de Angular, otra vez usando socket.io: https://github.com/mhevery/angular-node-socketio
EDITAR : para el n. ° 3, he estado usando Firebase para hacer esto.