1

我有一个看起来像这样的承诺链......

this.getFile(fileId).then(updateFile).then(displayAllDoneMessage);

wheregetFile()updateFile()each 用于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,以防万一。

4

2 回答 2

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

于 2014-01-31T13:08:43.743 回答
0

当您调用this.getFile时,上下文是this,在您的情况下,我猜this是 $scope 对象,所以this里面getFile是 $scope。

但是updateFileanddisplayAllDoneMessage被框架作为回调调用,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;
  };
}
于 2014-01-31T13:06:53.050 回答