8

重複の可能性:
angularjs-コントローラーでpromiseが解決されない

低速のWebSocketサーバーをAngularJSサービスでラップしてから、コントローラーからそのサービスを呼び出しています。コールバックをコールバックにチェーンすると、すべてが正常に機能し、UIは非同期で更新されます。

コールバックの混乱をクリーンアップするために使用しようとする$q.defer()と、遅延が呼び出されることはないようです。私はPythonのTwistedからの延期の概念に精通しているので、概念的にはすべてが機能するはずだと思いますが、そうではありません。

これは私が思いついた最短の例です。遅いWebSocketサーバーはsetTimeout関数でシミュレートされます。

<!doctype html>

<html ng-app="beta">
    <head>
        <title>Beta</title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.4/angular.min.js"></script>
        <script>
            var beta = angular.module('beta', []);

            var BetaCtrl = function ($scope, betaServ) {
                $scope.button = function () {
                    serv_result = betaServ.slow();
                    console.log(serv_result);

                    serv_result.then(function (result) {
                        console.log('callback finished');
                    });
                }
            }

            beta.service('betaServ', function($q) {
                this.slow = function () {
                    d = $q.defer()
                    setTimeout(function () {
                        console.log('before resolve');
                        d.resolve();
                        console.log('after resolve');
                    }, 2000);
                    return d.promise;
                }
            });
        </script>
    </head>
    <body>
        <div ng-controller="BetaCtrl">
            <button ng-click="button()">Run</button>
        </div>    
    </body>
</html>

は次のように実行する必要があります。

  1. ボタンクリック
  2. $ scope.button()が呼び出されます。service.slow()関数を呼び出します
  3. service.slow()は遅延を返します
  4. コールバックは据え置きに登録されます
  5. 延期された火災、登録されたコールバックのトリガー(この部分は発生しません)

何か案は?ありがとう。

4

1 に答える 1

29

Angularの外部で呼び出されるため、$applyを使用してコールバックを呼び出す必要があります。これはサービスであるため、サービスに$rootScopeを含める必要があります。

beta.service('betaServ', function($q, $rootScope) {
    this.slow = function () {
        d = $q.defer()
        setTimeout(function () {
            console.log('before resolve');
            $rootScope.$apply(d.resolve);
            console.log('after resolve');
        }, 2000);
        return d.promise;
    }
});
于 2013-01-25T21:01:50.880 に答える