我有一个看起来像这样的承诺链......
this.getFile(fileId).then(updateFile).then(displayAllDoneMessage);
其中getFile()
和updateFile()
各使用ngResource
来构建相应的JSON调用,然后返回$resource.$promise
。
链条触发正常,但我在$scope
updateFile
时遇到问题
所以getFile()
我有
// this works
this.status.text = "fetching file"
但在updateFile()
我有
// this fails at runtime because "this" is not $scope
this.status.text = "updating file"
我做错了什么,或者我需要做些什么才能在$scope
内提供updateFile()
?
我应该补充说,我正在使用TypeScript,以防万一。
答案 0 :(得分:3)
如果您正在使用TypeScript并且想要维护this
指针,那么您需要确保使用lambda语法。
假设您已将$scope
作为私有/公共变量保存在构造函数中,如下所示:
constructor(private $scope){ /* snip */ }
然后您可以这样做,以确保您正在访问$scope
,如此:
this.getFile(fileid)
.then((result) => {
return this.$scope.updateFile(result);
})
.then((result) => {
return this.$scope.displayAllDoneMessage(result);
});
在引擎盖下,这会被编译成如下所示:
//Save 'this' off to a closure
var _this = this;
_this.getFile(fileid)
.then(function(result){
return _this.$scope.updateFile(result);
})
.then(function(result){
return _this.$scope.displayAllDoneMessage(result);
});
TypeScipt使用闭包来维护对this
答案 1 :(得分:0)
当您致电this.getFile
时,上下文为this
,在您的情况下,我猜this
是$ scope对象,因此this
内的getFile
是$ scope。
但框架会调用updateFile
和displayAllDoneMessage
作为回调,this
不再引用$ scope。
尝试.bind将$ scope绑定为上下文:
this.getFile(fileId).then(updateFile.bind(this)).then(displayAllDoneMessage.bind(this));
对于旧版浏览器,您可以将此脚本包含为polyfill(引自文档):
if (!Function.prototype.bind) {
Function.prototype.bind = function (oThis) {
if (typeof this !== "function") {
// closest thing possible to the ECMAScript 5 internal IsCallable function
throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
}
var aArgs = Array.prototype.slice.call(arguments, 1),
fToBind = this,
fNOP = function () {},
fBound = function () {
return fToBind.apply(this instanceof fNOP && oThis
? this
: oThis,
aArgs.concat(Array.prototype.slice.call(arguments)));
};
fNOP.prototype = this.prototype;
fBound.prototype = new fNOP();
return fBound;
};
}