【问题标题】:AngularJS 1.4 with ES6 Classes, this is null [duplicate]带有 ES6 类的 AngularJS 1.4,这是 null [重复]
【发布时间】:2015-12-02 10:48:01
【问题描述】:

目前有点与此作斗争,因为我不明白为什么会这样。我会告诉你控制器。

class ExampleClassController {
    constructor($scope, serviceItem, PrepService, consts) {
        // Services
        this.serviceItem = serviceItem;

        // Init Values
        this.grid = PrepService;
        this.dates = [
            moment().format('x'),
            moment().add(14, 'days').format('x')
        ];
        // Works fine
        console.log(this._init());

        // Events
        $scope.$on(consts.events.change, this._init);
    }

    _init() {
        // this.grid = {};
        // Returns null
        console.log(this, "in the init");
        return this.serviceItem.get().then((res) => this.grid = res);
    }
}

这是奇怪的部分,当我在构造函数中调用 this._init 时,它很好。按照建议返回承诺。但是当我在 $scope.$on 事件中调用它时,它就会崩溃并说这是空的。我似乎无法弄清楚它为什么会发生,因为它似乎没有发生在其他任何人的例子中。任何事情都会有所帮助,只是了解为什么会很棒。

谢谢!

【问题讨论】:

  • 您在使用回调时丢失了对this 的引用。你可以在$scope.$on中做this._init.bind(this)
  • 你是怎么知道在_init中使用箭头函数的? .then((res) => this.grid = res); - 将相同的逻辑应用于您的 constructor

标签: javascript angularjs ecmascript-6


【解决方案1】:

正如@Pierrickouw 在您的问题中指出的那样,您正在失去对this 的引用。 不过,您有多种选择来克服这个问题:

  • 使用 Function.prototype.bind 方法

    // Events
    $scope.$on(consts.events.change, this._init.bind(this));
    
  • 使用箭头函数(具有保持正确上下文的属性)

    // Events
    $scope.$on(consts.events.change, () => this._init());
    
  • 使用角度绑定函数(这只是第一个选项的变体)

    // Events
    $scope.$on(consts.events.change, angular.bind(this, this._init));
    

作为最佳实践,您应该根据您的用例场景使用绑定或箭头函数。

  1. 如果您只想使用正确的上下文委派您的处理程序,请使用.bind

    // .bind(theRightContext), e.g. this or $scope
    $scope.on('someEvent', this._init.bind(this));
    
  2. 如果你想做一些预计算,你应该使用arrow function

    $scope.on('someEvent', () => {
            // do some computations here
            console.log('will now call someMethod on', this);
            this.someMethod();
    });
    

注意 ES6 中的 arrow function 等同于在 ES5 中使用 .bind

$scope.on('someEvent', function() {
        // do some computations here
        console.log('will now call someMethod on', this);
        this.someMethod();
}.bind(this));

【讨论】:

  • 您认为最佳做法是什么?我喜欢 .bind(this) 方法,但这只是因为它更具视觉吸引力。我觉得 .bind 是要走的路,但不确定。
猜你喜欢
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
  • 2023-03-20
  • 2017-04-13
  • 2017-07-29
相关资源
最近更新 更多