相关内容:https://jsfiddle.net/tqf4zea7/1/
我在angular控制器中使用$q。为了测试一些场景,我在作用域上创建了一个数组,将消息推送到:
$scope.messages = [];
我设置了一个返回$q函数的函数,如下所示:
function returnAPromise(valToReturn){
return $q(function(resolve, reject){
$timeout(function(){
resolve(valToReturn);
}, 500);
});
}
然后我有一个.then()
调用的结果看起来像这样:
returnAPromise('third').then($scope.messages.push);
由于我只想将承诺解析的值推入数组,因此我认为我可以传入消息数组的push方法,但是当我这样做时,我得到以下错误:
VM289 angular.js:12520 TypeError: Array.prototype.push called on null or undefined
at processQueue (VM289 angular.js:14792)
at VM289 angular.js:14808
at Scope.$eval (VM289 angular.js:16052)
at Scope.$digest (VM289 angular.js:15870)
at Scope.$apply (VM289 angular.js:16160)
at VM289 angular.js:17927
at completeOutstandingRequest (VM289 angular.js:5552)
at VM289 angular.js:5829
如果我在一个函数中包含push,它工作得很好:
returnAPromise('third').then(function(message){
$scope.messages.push(message)
});
这是我不理解的闭包问题吗?
你需要绑定push,因为它使用this
returnAPromise('third').then($scope.messages.push.bind($scope.messages));
我知道有一个公认的答案,但我将在这里解释得更清楚
<标题> 例子让我们从一个例子
开始var scope = {
scopeFn: function() {
console.log('this', this)
}
}
function callFn(fn) {
fn();
}
callFn(obj.scopeFn) // will log window object
callFn(function() {
obj.scopeFn();
});// will log scope object
正如你所看到的,包装函数将给被调用的对象this的值,但是直接调用它而不包装它将调用window对象。
<标题>为什么? this
将绑定到它调用的对象。
在第一个示例callFn(obj.scopeFn)
中,您将函数作为参数传递,因此当函数被调用时,它直接被调用,而不是从scope
对象。(scope
对象丢失,只发送函数引用)。
从对象调用函数scopeFn
,因此this
将绑定到它的对象。(scope
对象不会丢失,因为当它被调用时整个东西都在那里)
要解决这个问题,你需要绑定你传递的函数作为解析的参数,这样它将总是被调用,就像它是从它的父对象调用一样。
var scopeMessage = $scope.messages;
returnAPromise('third').then(scopeMessage.push.bind(scopeMessage));
标题>标题>标题>