Angular 5回调,那=这个

时间:2018-05-14 16:22:20

标签: javascript angular callback this

在我的Angular 5项目中,我对来自外部库的回调有一些问题。我用

加载它
<script src="https://js.chargebee.com/v2/chargebee.js" data-cb-site="my-site"> </script>

然后在Angular中我将其导入如下:

declare var Chargebee: any;
Chargebee.init({site: "my-site"});

我的组件中也有一个公共变量,比方说publicVar,我在模板中显示。

publicVar: string = 'before checkout';

我有以下方法:

subscribeToPlan() {
  var _self = this;
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: function() {
      _self.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: function(hostedPageId) {
      _self.publicVar = 'success';
      console.log('success');
    },
    close: function() {
      _self.publicVar = 'closed';
      console.log('closed');
    }
  });
}

运行代码时发生了什么?

所有console.log函数都输出正确的数据,因此我知道调用chargebee回调函数。但是,只有hostedPage: function() {}才能正确更改我的publicVar,并且会显示&#34; hosted-page&#34;在我的模板中。

success: function(){}close: function(){}无法更新模板中的publicVar。我怀疑,因为这些与hostedPage不同,回调方法和其中的self.有错误的上下文?

2 个答案:

答案 0 :(得分:1)

您可以使用不会影响_self范围的箭头函数,而不是将其分配给某个变量this

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => {
      this.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: hostedPageId => {
      this.publicVar = 'success';
      console.log('success');
    },
    close: () => {
      this.publicVar = 'closed';
      console.log('closed');
    }
  });
}

没有记录,这就变得更加整洁:

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => this.publicVar = 'hosted-page',
    success: hostedPageId => this.publicVar = 'success',
    close: () => this.publicVar = 'closed'
  });
}

虽然我认为您的代码应该可以正常工作。您已将this分配给_self并使用该功能,因此this功能不重要。我绝对建议放入一个断点并检查这两个函数中的_self是什么。

答案 1 :(得分:0)

所以我解决了(或找到了解决方法)

由于_self确实保存了正确的数据,我认为不会为这些回调触发更改检测。在我手动触发它之后,一切都按预期工作。

最终代码和更改:

导入

import { ChangeDetectorRef } from '@angular/core';

将其添加到构造函数:

constructor(private cd: ChangeDetectorRef)

然后在回调方法结束时调用它,这将手动触发Angular变化检测,并更新publicVar的模板呈现

subscribeToPlan() {
  var _self = this;
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: function() {
      _self.publicVar = 'hosted-page';  // This is not a callback, so it just works
      console.log('hosted-page');
    },
    success: function(hostedPageId) {
      console.log('success');
      _self.publicVar = 'success';
      _self.cd.detectChanges();  // Manual change detection
    },
    close: function() {
      console.log('closed');
      _self.publicVar = 'closed';
      _self.cd.detectChanges();  // Manual change detection
    }
  });
}

使用箭头功能的替代代码,根据Joe的建议(https://stackoverflow.com/a/50335020/5644425

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => {
      this.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: hostedPageId => {
      console.log('success');
      this.publicVar = 'success';
      this.cd.detectChanges();
    },
    close: () => {
      console.log('closed');
      this.publicVar = 'closed';
      this.cd.detectChanges();
    }
  });
}