Nice programing

외부 앱이 영구 모델 (서버 데이터베이스)을 변경 한 경우 AngularJS가 뷰를 자동 업데이트 할 수 있습니까?

nicepro 2020. 10. 5. 20:54
반응형

외부 앱이 영구 모델 (서버 데이터베이스)을 변경 한 경우 AngularJS가 뷰를 자동 업데이트 할 수 있습니까?


방금 AngularJS에 익숙해지기 시작했지만 서버 측 데이터베이스에서 무언가 변경 될 때 사용자를 위해 실시간 (새로 고침 없음)으로 자동 업데이트되는보기가있는 웹 앱을 빌드하고 싶습니다.

AngularJS가 이것을 (대부분) 자동으로 처리 할 수 ​​있습니까? 그렇다면 기본 메커니즘은 무엇입니까?

예를 들어, "모델"변경에 대해 정기적으로 DB를 폴링하도록 AngularJS를 어떻게 설정합니까? 아니면 일종의 Comet과 같은 메커니즘을 사용하여 모델이 변경되었음을 AngularJS 클라이언트 측 코드에 알릴 수 있습니까?

내 응용 프로그램에서 문제는 다른 (웹이 아닌) 서버 측 소프트웨어가 때때로 데이터베이스를 업데이트한다는 것입니다. 그러나이 질문은 AngularJS 웹 클라이언트를 통해 데이터베이스를 변경하는 여러 클라이언트가있을 수있는 순수 웹 앱에도 동일하게 적용되며, 이들 중 하나가 DB (모델)를 변경할 때 각각 업데이트해야합니다.


몇 가지 선택이 있습니다 ...

  1. 다음을 사용하여 모든 X 밀리 초 폴링을 할 수있는 $timeout$http, 또는 당신이 사용하고있는 데이터가 REST 서비스에 후크 최대 인 경우, 당신은 사용할 수 있습니다 $resource대신 $http.

  2. 일부 Websocket 구현을 사용 scope.$apply하고 소켓에 의해 푸시되는 변경 사항을 처리 하는 데 사용하는 서비스를 만들 수 있습니다 . 다음은 node.js 웹 소켓 라이브러리 인 socket.io를 사용하는 예입니다.

    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. 정말 첨단 기술을 얻고 Angular 모델을 서버와 동기화하는 웹 소켓 구현을 만들 수 있습니다. 클라이언트가 무언가를 변경하면 해당 변경 사항이 자동으로 서버로 전송됩니다. 또는 서버가 변경되면 클라이언트로 전송됩니다.
    다음은 이전 버전의 Angular에서 다시 socket.io를 사용하는 예입니다. https://github.com/mhevery/angular-node-socketio

편집 : # 3의 경우 Firebase사용 하여이 작업을 수행했습니다.


다음은 node 대신 jetty를 사용하는 구현입니다. angularjs 부분은 angular-seed 앱을 기반으로합니다. 각도 코드가 관용적인지 확실하지 않지만 작동하는지 테스트했습니다. 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>

What you are looking for is Firebase and Deployd. Firebase comes with an adapter too that makes using it a breeze: http://angularfire.com/


According to the "Discover Meteor" book, Angular watches/scopes are similar to Meteor's computations regarding reactivity... but Angular is client-only and gives less-granular control than Meteor.

My impression is that using Angular might be a better fit for adding reactivity to an existing app, whereas Meteor soars when you use it for the whole thing. But I have no real experience with Angular yet (though I have built some small Meteor apps).


So, Andy Joslin has mentioned the best solution in my opnion in his answer, the 3rd option, which is to maintain state bidirectionally via websockets or whatever other async library you're dealing with (this would be the Chrome message API for Chrome Extensions and Apps for instance), and toddg has given an example of how that would be achieved. However, in his example he is implementing an anti-pattern in AngularJS: the service is calling the controller. Instead, the model should be placed inside the service, and then referenced from the controller.

The service socket callbacks will modify the service model, and because it is referenced from the controller, it will update the view. Careful if you're dealing with primitive data types or variables that can be reassigned though, those will need a watch on the controller to make this work.

참고URL : https://stackoverflow.com/questions/11276520/can-angularjs-auto-update-a-view-if-a-persistent-model-server-database-is-chan

반응형