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


81

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

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

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

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


Meteor가 프레임 워크에서이 모든 작업을 수행한다는 사실을 발견 한 이후로 이것이 제가 선호하는 솔루션이라는 사실을 추가하고 싶습니다. 나중에 Angular를 다시 확인할 수 있습니다.
jpeskin

Meteor는 여전히 "신선한"상태 일 수 있습니다. 장난을 치는 것은 좋지만 대규모 생산에서는 입증되지 않았습니다 (안전 / 확장 성 / 성능 등). 인증은 한 달 넘게 추가되었습니다. 좋아 보이지만 기다릴 것입니다.
Alex Okrushko

@jpeskin 안녕하세요. 나는 당신이이 질문을했을 때 정확히 어디에 있었는지에 대한 것입니다. 당신은 무엇을하게 되었습니까? (나는 Angular를 사용하고 싶습니다). 감사합니다 Mark
mark1234 2014-06-16

답변:


97

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

  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 를 사용 하여이 작업을 수행했습니다.


몇 가지 옵션으로 철저한 답변을 해주셔서 감사합니다! Angular에 대해 더 많이 배우면서 이해하기를 기대합니다. :)
jpeskin

4
github.com/mhevery/angular-node-socketio- 철자 오류가 있습니다. 그것을 고정
앤드류 조슬린

이해하기 쉬운 답장을 주셔서 감사합니다.
mystrdat 2012-07-17

컨트롤러를 파괴해야하는 경우 이벤트 핸들러의 바인딩을 어떻게 해제 하시겠습니까?
RushPL

Brian ford는 $ scope의 이벤트 시스템 및 정리에 편승 할 수있는 훌륭한 접근 방식을 가지고 있습니다. 그리고 일반적으로 정말 깨끗하게 만듭니다. github.com/btford/angular-socket-io . socket.forward ()보세요
Andrew Joslin

15

다음은 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>

이것은 훌륭한 예입니다. Angular.js를 배우는 중이며 배울 수있는 템플릿 등이있는 완전한 앱이 있는지 궁금합니다.
mac


0

"Discover Meteor"책에 따르면 Angular 시계 / 스코프는 반응성에 관한 Meteor의 계산과 유사하지만 Angular는 클라이언트 전용이며 Meteor보다 덜 세분화 된 제어를 제공합니다.

내 인상은 Angular를 사용하는 것이 기존 앱에 반응성을 추가하는 데 더 적합 할 수있는 반면 Meteor는 전체적으로 사용할 때 치솟는 것입니다. 그러나 Angular에 대한 실제 경험은 아직 없습니다 (작은 Meteor 앱을 만들었지 만).


0

그래서 Andy Joslin은 내 의견에서 최고의 솔루션을 언급했습니다. 세 번째 옵션은 웹 소켓 또는 처리중인 다른 비동기 라이브러리를 통해 양방향으로 상태를 유지하는 것입니다 (이는 Chrome 확장 프로그램 용 Chrome 메시지 API 및 예를 들어 앱), 그리고 toddg는 그것이 어떻게 달성 될 것인지에 대한 예를 제공했습니다. 그러나 그의 예에서 그는 AngularJS에서 안티 패턴을 구현하고 있습니다. 서비스는 컨트롤러를 호출하고 있습니다. 대신 모델을 서비스 내부에 배치 한 다음 컨트롤러에서 참조해야합니다.

서비스 소켓 콜백은 서비스 모델을 수정하고 컨트롤러에서 참조되기 때문에 뷰를 업데이트합니다. 재 할당 할 수있는 원시 데이터 유형이나 변수를 처리하는 경우주의해야합니다. 컨트롤러에 대한 감시가 필요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.