AngularJS范围和Deferreds [英] AngularJS Scopes and 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
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屋!