我有做一些事情很難,並返回一個承諾服務: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