2

私は何か難しいことをして約束を返すサービスを持っています:

.factory('myService', function($q) {

    return {
        doSomethingHard: function() {
            var deferred = $q.defer();

            setTimeout(function() {
                deferred.resolve("I'm done!");
            }, 1000);

            return deferred.promise;
        }
    };
})

そのサービスを使用してスコープに関数を追加するコントローラーがあります。

.controller('MyCtrl', function($scope, myService) {

    $scope.doSomething = function() {
        var promise = myService.doSomethingHard();

        promise.then(function(result) {
            alert(result);
        });
    };

})

ディレクティブを使用して、属性を解析してそのコントローラー関数を呼び出します。

.directive('myDirective', function($parse) {
    return {
        link: function(scope, el, attr) {

            var myParsedFunction = $parse(attr.myDirective);

            el.bind('click', function() {
                myParsedFunction(scope);
            });
        }
    };
})

テンプレートで

<div ng-controller="MyCtrl">
    <button my-directive="doSomething()">The Button</button>
</div>

ボタンをクリックするとイベント リスナーがトリガーされ、コントローラー関数doSomethingが呼び出され、サービス関数が呼び出されdoSomethingHardてプロミスTHAT IS NEVER RESOLVEDが返されます。

ここですべてをフィドルにアップします:

http://jsfiddle.net/nicholasstephan/RgKaT/

何を与える?

ありがとう。

編集: Maksym H. のおかげで、promise resolve をラップする$scope.$apply()とコントローラーで発火するようです。私はhttp://jsfiddle.net/RgKaT/4/をうまくいじっています。しかし、私は自分のサービスからスコープを外したいと思っています。

また、なぜこれが機能するのかを知りたいです。または、さらに良いことに、適用範囲にラップされている間に約束を解決しないと機能しないのはなぜですか。Angular の世界全体と通常の Javascript の世界のアナロジーは、変更を消化する必要があるプロパティについて考えるときに理にかなっていますが、これは約束です... コールバック関数を使用します。$q は Promise に解決済みのフラグを立て、スコープがそのプロパティの更新を消化し、解決済みのハンドラー関数を起動するのを待つだけですか?

4

2 に答える 2

2

別の方法は次のとおりです。ディレクティブでスコープを定義し、この属性をバインドして親スコープを期待するようにしてください。

.directive('myDirective', function() {
  return {
    scope: { myDirective: "=" }, // or { myParsedFunction: "=myDirective" },
    link: function(scope, el, attr) {

        el.bind('click', function() {
            scope.myDirecive(scope); // or scope.myParsedFunction(scope)
        });
    }
  };
})

しかし、重要なことは、しばらくして解決するときにダイジェストを実行することです。

.factory('myService', function($q, $timeout) {

    return {
        doSomethingHard: function() {
            alert('3. doing something hard');

            var deferred = $q.defer();

            // using $timeout as it's working better with promises
            $timeout(function() {
                alert('4. resolving deferred');
                deferred.resolve('Hello World!'); // Here...
            }, 1000);

            return deferred.promise;
        }
    };
})

jsフィドル

PS HTMLの「()」でこれを適用しない親スコープのモデルとしてメソッドを渡していることを確認してください

<button my-directive="doSomething">Button</button>

于 2013-04-21T21:22:26.457 に答える
1

setTimeoutに置き換えるだけです$timeout(そして、サービスに注入することを忘れないで$timeoutください)。これが更新された jsFiddleです。

于 2013-05-10T18:35:07.423 に答える