为什么我必须在typescript角度控制器函数中重新声明属性

时间:2016-02-15 15:19:19

标签: angularjs typescript

export interface IFooModel {
    foo:string;
    fooFunction(fooProp:string):void;
}

 export class FooCtrl implements IFooModel {
    constructor(public foo:string){
    }

    fooFunction(fooProp:string):void{
    }
}

上面的代码是相当标准的。我的问题是,当我想在函数中访问foo:string时我必须这样做

fooFunction(fooProp:string):void{
   var fooAgain = this.foo;

  // Pretend i set it up properly for $mdDialog to work
  this.$mdDialog.show(options).then(function(answer: boolean) {
       if (answer) {
             // fooAgain works
             // this.foo does not work 
       }
}

为什么我必须将this.foo设置为变量才能在另一个函数中访问它,而不是只写this.foo?在某些函数中,我最终得到了大约4个已经在构造函数中声明的变量声明。有没有更好的方法呢?我觉得控制器中的重复代码太多了。

2 个答案:

答案 0 :(得分:2)

是的,这是Javascript中的一个问题,但幸运的是在TypeScript中,这个问题已经不再多亏了胖箭了!耶!

胖箭头就像匿名函数,但为你处理this变量。 让我告诉你:

fooFunction(fooProp:string):void {
    // Pretend i set it up properly for $mdDialog to work
    this.$mdDialog.show(options).then((answer: boolean) => {
        if (answer) {
            this.foo = "";  
        }
     });
}

使用胖箭头,现在将在JS中编译为:

FooCtrl.prototype.fooFunction = function (fooProp) {
    var _this = this;
    // Pretend i set it up properly for $mdDialog to work
    this.$mdDialog.show(options).then(function (answer) {
        if (answer) {
            _this.foo = "";
        }
    });
};

因此,Typescript会自动为您创建一个_this变量,以便您不再遇到问题。如果你问我,那很漂亮。

这里是Arrow功能的文档: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions

答案 1 :(得分:1)

在调用函数之前将值放在局部变量中的唯一原因是因为您希望类超出范围(即会发生更改范围的事情,例如回调或异步操作)。 / p>

通过将值放在局部变量中,它将成为函数闭包的一部分,并且值与函数本身一起存储。

这是JavaScript最棘手的方面之一 - 范围有点时髦。

还有其他选择可以解决这个问题,包括胖箭......

() => {
    // this.foo is now preserved
}

call / apply,可让您设置范围。