81

私は AngularJS に慣れ始めたばかりですが、サーバー側のデータベースで何かが変更されたときに、ユーザーのためにリアルタイムで自動更新される (更新なし) ビューを持つ Web アプリを構築したいと考えています。

AngularJS はこれを (ほとんど) 自動的に処理できますか? もしそうなら、どのような基本的なメカニズムが働いているのでしょうか?

たとえば、「モデル」の変更を定期的に DB にポーリングするように AngularJS を設定していますか? それとも、ある種のコメットのようなメカニズムを使用して、モデルが変更されたことを AngularJS のクライアント側コードに通知しますか?

私のアプリケーションでの課題は、他の (Web 以外の) サーバー側ソフトウェアが時々データベースを更新することです。しかし、この質問は、複数のクライアントが AngularJS Web クライアントを介してデータベースを変更する可能性がある純粋な Web アプリにも同様に当てはまり、そのうちの 1 つが DB (モデル) に変更を加えたときにそれぞれを更新する必要があります。

4

5 に答える 5

97

いくつかの選択肢があります...

  1. $timeoutandを使用して X ミリ秒ごとにポーリングを実行できます。または、使用しているデータが REST サービスに接続されている場合は、代わりに を$http使用できます。$resource$http

  2. いくつかの Websocket 実装を使用するサービスを作成scope.$applyし、ソケットによってプッシュされた変更を処理するために使用できます。node.js websocket ライブラリである 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 モデルをサーバーと同期する Websocket 実装を作成することができます。クライアントが何かを変更すると、その変更は自動的にサーバーに送信されます。または、サーバーが変更された場合は、クライアントに送信されます。
    これは古いバージョンの Angular での例で、再び socket.io を使用しています: https://github.com/mhevery/angular-node-socketio

編集: #3 については、これを行うためにFirebaseを使用しています。

于 2012-06-30T21:18:32.357 に答える
15

node の代わりに jetty を使用する実装を次に示します。angularjs 部分は angular-seed アプリに基づいています。angularコードが慣用的であるかどうかはわかりません...しかし、これが機能することをテストしました。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>
于 2012-07-04T15:24:28.347 に答える
0

「Discover Meteor」本によると、Angular のウォッチ/スコープは、反応性に関する Meteor の計算に似ていますが、Angular はクライアントのみであり、Meteor よりも詳細な制御ができません。

私の印象では、Angular を使用すると、既存のアプリに反応性を追加するのにより適している可能性がありますが、Meteor は全体に使用すると高くなります。しかし、私はまだ Angular の実際の経験がありません (いくつかの小さな Meteor アプリを作成しましたが)。

于 2013-10-23T16:14:02.350 に答える
0

したがって、Andy Joslin は、彼の回答で私の意見で最良の解決策について言及しました。3 番目のオプションは、Websockets またはその他の処理している非同期ライブラリを介して双方向に状態を維持することです (これは、Chrome 拡張機能用の Chrome メッセージ API であり、アプリなど)、toddg はそれを実現する方法の例を挙げています。ただし、彼の例では、AngularJS でアンチパターンを実装しています。つまり、サービスがコントローラーを呼び出しています。代わりに、モデルをサービス内に配置し、コントローラーから参照する必要があります。

サービス ソケット コールバックはサービス モデルを変更し、コントローラーから参照されるため、ビューを更新します。ただし、再割り当て可能なプリミティブ データ型または変数を扱う場合は注意が必要です。これを機能させるには、コントローラーを監視する必要があります。

于 2014-02-18T15:12:43.260 に答える