Zaczynam dopiero zapoznawać się z AngularJS, ale chciałbym zbudować aplikację internetową, która ma widok, który jest automatycznie aktualizowany w czasie rzeczywistym (bez odświeżania) dla użytkownika, gdy coś się zmieni w bazie danych po stronie serwera.
Czy AngularJS może sobie z tym poradzić (w większości) automatycznie? A jeśli tak, to jaki jest podstawowy mechanizm w działaniu?
Na przykład, czy w jakiś sposób skonfigurowałeś AngularJS tak, aby regularnie sprawdzał bazę danych pod kątem zmian „modelu”? Albo użyć jakiegoś mechanizmu podobnego do Comet, aby powiadomić kod klienta AngularJS o zmianie modelu?
W mojej aplikacji wyzwaniem jest to, że inne (inne niż internetowe) oprogramowanie po stronie serwera będzie czasami aktualizować bazę danych. Ale to pytanie dotyczy w równym stopniu aplikacji internetowych, w których może być wielu klientów zmieniających bazę danych za pośrednictwem klientów sieciowych AngularJS i każdy z nich musi zostać zaktualizowany, gdy jeden z nich dokona zmiany w DB (modelu).
źródło
Odpowiedzi:
Masz kilka możliwości ...
Możesz przeprowadzić odpytywanie co X milisekund przy użyciu
$timeout
i$http
, lub jeśli dane, których używasz, są podłączone do usługi REST, możesz użyć$resource
zamiast$http
.Można utworzyć usługę, która używa pewnej implementacji Websocket i używa
scope.$apply
do obsługi zmian wypychanych przez gniazdo. Oto przykład użycia socket.io, biblioteki 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); }; }
Możesz uzyskać naprawdę zaawansowaną technologię i stworzyć implementację websocket, która zsynchronizuje model Angular z serwerem. Kiedy klient coś zmienia, ta zmiana jest automatycznie wysyłana na serwer. Lub jeśli serwer się zmieni, zostanie wysłany do klienta.
Oto przykład tego w starej wersji Angular, ponownie przy użyciu socket.io: https://github.com/mhevery/angular-node-socketio
EDYCJA : W przypadku # 3 używam do tego Firebase .
źródło
Oto implementacja, która używa molo zamiast węzła. Część angularjs jest oparta na aplikacji angular-seed. Nie jestem pewien, czy kod kątowy jest idiomatyczny ... ale przetestowałem, że to działa. HTH -Todd.
TimerWebSocketServlet patrz
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>
źródło
Co szukasz jest Firebase i Deployd . Firebase jest również wyposażony w adapter, dzięki któremu korzystanie z niego jest dziecinnie proste: http://angularfire.com/
źródło
Zgodnie z książką „Discover Meteor”, zegarki / lunety Angular są podobne do obliczeń Meteor w zakresie reaktywności ... ale Angular jest tylko klientem i zapewnia mniej szczegółową kontrolę niż Meteor.
Mam wrażenie, że używanie Angulara może lepiej nadawać się do dodawania reaktywności do istniejącej aplikacji, podczas gdy Meteor szybuje, gdy używasz go do całości. Ale nie mam jeszcze prawdziwego doświadczenia z Angularem (chociaż zbudowałem kilka małych aplikacji Meteor).
źródło
Tak więc Andy Joslin wspomniał w swojej odpowiedzi o najlepszym rozwiązaniu z mojej opinii, trzeciej opcji, która polega na dwukierunkowym utrzymywaniu stanu za pośrednictwem gniazd sieciowych lub jakiejkolwiek innej biblioteki asynchronicznej, z którą masz do czynienia (byłby to interfejs API wiadomości Chrome dla rozszerzeń Chrome i Apps na przykład), a toddg podał przykład, jak można to osiągnąć. Jednak w swoim przykładzie implementuje anty-wzorzec w AngularJS: usługa wywołuje kontroler. Zamiast tego model należy umieścić w usłudze, a następnie odwołać się do niego z kontrolera.
Wywołania zwrotne gniazda usługi zmodyfikują model usługi, a ponieważ odwołuje się do niego kontroler, zaktualizuje widok. Ostrożnie, jeśli masz do czynienia z prymitywnymi typami danych lub zmiennymi, które można ponownie przypisać, będą one wymagały zegarka na kontrolerze, aby to zadziałało.
źródło