我有做一些事情很难,并返回一个承诺服务:AngularJS范围和Deferreds
.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
,它返回一个承诺,是永远不会分辨。
整件事在这里小提琴:
http://jsfiddle.net/nicholasstephan/RgKaT/
是怎么回事?
谢谢。
编辑:感谢Maksym阁下,它看起来像包装承诺决心在$scope.$apply()
使它在控制器的火灾。我有一个工作小提琴http://jsfiddle.net/RgKaT/4/。但我真的很想保持我的服务范围。
我也很想知道为什么这个工程。或者更好的是,为什么它在包装在范围应用中时不解决承诺是行不通的。整个Angular世界与常规的Javascript世界比喻在考虑属性变化时需要消化时才有意义,但这是一个承诺...具有回调函数。 $ q是否只将promise标记为已解决,并等待范围消化该属性更新并释放其已解析的处理函数?
@nicholas,我已经更新了Plunker上的代码。我希望它能为你工作。 – Maksym 2013-04-21 22:28:16
真棒回答。谢谢。我已经通过将$ rootScope添加到服务中,像你所建议的那样工作。谢谢。但是,我仍然不是很高兴,也不了解这个解决方案(请参阅我的编辑)。 – nicholas 2013-04-22 20:18:41
@nicholas,你不用担心,因为它是原生setTimeout的错。通过使用这个,agnular似乎停止观看解决。在实际的例子中,你可能会使用XHR erquest之类的东西,并成功解决,对吧?但是现在,您可以使用角度$超时提供程序进行测试,该提供程序在角度许诺方面效果更好。而且你可以尝试用XHR请求来解决问题,它应该可以工作。这里更新小提琴(http://jsfiddle.net/RgKaT/6/) – Maksym 2013-04-23 08:44:27