AngularJS范围和Deferreds [英] AngularJS Scopes and Deferreds

查看:177
本文介绍了AngularJS范围和Deferreds的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有做一些事情很难,并返回一个承诺服务:

I have a service that does something hard and returns a promise:

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

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

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

            return deferred.promise;
        }
    };
})

我有一个控制器,使用该服务增加了一个功能,范围:

I have a controller that adds a function to the scope using that service:

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

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

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

})

我用一个指令通过解析一个属性调用该控制器功能:

I use a directive to call that controller function by parsing an attribute:

.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 ,它返回一个承诺,,它永远不会分辨即可。

Clicking the button triggers the event listener, which calls the controller function doSomething, which calls the service function doSomethingHard, which returns a promise, THAT IS NEVER RESOLVED.

整个事情了一个小提琴这里:

Whole thing up on a fiddle here:

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

怎么办?

感谢。

编辑:感谢马克西姆·H.,它看起来像在 $范围包裹的承诺的决心$适用()使得火英寸控制器。我有一个工作小提琴起来 http://jsfiddle.net/RgKaT/4/ 。但我真的很想保留的范围了我的服务。

Thanks to Maksym H., It looks like wrapping the promise resolve in $scope.$apply() makes it fire in the controller. I've got a working fiddle up http://jsfiddle.net/RgKaT/4/. But I'd really like to keep the scope out of my services.

我也很想知道为什么这个工程。或者更好的是,为什么它不不解决的承诺,而包裹在一个范围内申请工作。整个世界的角度VS规则的Javascript世界的类比是有道理的思考性质的改变需要被消化的时候,但是这是一个承诺......有回调函数。请问$ Q刚刚旗承诺为已解决,等待范围消化的属性更新,并触发其解决处理函数?

I'd also really like to know why this works. Or better yet, why it doesn't work without resolving the promise while wrapped in a scope apply. The whole Angular world vs regular Javascript world analogy makes sense when thinking about properties as changes need to be digested, but this is a promise... with callback functions. Does $q just flag the promise as resolved and wait for the scope to digest that property update and fire its resolved handler functions?

推荐答案

下面是另一种方式:尝试指令来定义范围,并结合本ATTR期望父母范围

Here is another way: Try to define scope in directive and bind this attr to expect parent scope.

.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)
        });
    }
  };
})

但主要的一点就是运行消化,当你经过一段时间解决它:

But the main thing is to run digest when you resolving it after some time:

.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;
        }
    };
})

的jsfiddle

jsFiddle

P.S。请确保您传递方法父范围的模型不适用本所()中的HTML

P.S. Make sure you are passing method as model of parent scope not applying this by "()" in HTML

&LT;按钮我-指令=DoSomething的&GT;按钮&LT; /按钮&GT;

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

这篇关于AngularJS范围和Deferreds的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆