AngularJS范围和延迟
我有一个服务,做了一些艰难的事情,并回报一个承诺:AngularJS范围和延迟,angularjs,angularjs-directive,promise,angularjs-scope,Angularjs,Angularjs Directive,Promise,Angularjs Scope,我有一个服务,做了一些艰难的事情,并回报一个承诺: .factory('myService', function($q) { return { doSomethingHard: function() { var deferred = $q.defer(); setTimeout(function() { deferred.resolve("I'm done!");
.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
,该函数返回一个承诺,,该承诺永远不会解决
整件事都摆在这里:
有什么好处
谢谢
编辑:多亏了Maksym H,它看起来像是将承诺解析包装在$scope中。$apply()
使其在控制器中启动。我有一把小提琴正在演奏。但我真的不想让这个范围出现在我的服务中
我也很想知道为什么会这样。或者更好的是,为什么它在包装在一个作用域apply中时没有解析承诺就不能工作。当考虑属性时,整个角度世界与常规Javascript世界的类比是有意义的,因为需要消化更改,但这是一个承诺。。。使用回调函数。$q是否只是将承诺标记为已解决,并等待作用域消化该属性更新并触发其已解决的处理程序函数 还有另一种方法:尝试在指令中定义作用域,并将此属性绑定到父作用域
.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;
}
};
})
另外,请确保您将方法作为父范围的模型传递,而不是通过HTML中的“()”应用此方法
按钮
只需将设置超时
替换为$timeout
(记住将$timeout
注入您的服务中)。这是一个。@nicholas,我已经更新了Plunker的密码。我希望它对你有用。回答得真棒。谢谢我已经按照您的建议,通过向服务中添加$rootScope实现了这一点。谢谢但我仍然对这个解决方案不太满意,也不理解(见我的编辑)。@nicholas,你不必担心,因为这是本机设置超时的错。使用此选项后,agnular似乎不再关注解析。在实际示例中,您可能会使用XHR erquest和resolve on success之类的工具,对吗?但是现在您可以使用angular的$timeout提供程序来测试它,该提供程序在angular承诺中工作得更好。此外,您还可以尝试使用XHR请求进行解析,它应该可以正常工作。这里是更新的提琴()啊。这是有道理的。解析一个属性,这样我就不必为该指令创建一个孤立的作用域,这也很有效。在我的生产代码中,除了使用$http而不是$timeout之外,其他代码都是相同的,我仍然必须编写$scope.$apply(fn)
,而不仅仅是fn()
,这有点奇怪,但问题一定来自其他地方。为了我自己的教育,我会试着复制一把小提琴,但现在它起作用了,这对我来说已经足够好了。谢谢。即使承诺没有解决,这个返回不是在1秒后完成吗?