javascript - Angular 5回调和that=this

标签 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"});

我的组件中也有一个公共(public)变量,比方说 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,并且它在我的模板中显示为“hosted-page”。

success: function(){}close: function(){} 都不会更新我模板中的 publicVar。我怀疑是因为与 hostedPage 不同,它们是一个回调方法,而其中的 self. 上下文错误?

最佳答案

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

由于 _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();
    }
  });
}

关于javascript - Angular 5回调和that=this,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50334905/

相关文章:

angular - 如何将来自不同延迟加载模块的两个组件绑定(bind)到同一路由?

asp.net-mvc-5 - 在现有 MVC 5 应用程序中使用 Angular JS

javascript - 将简单函数直接传递给 es6 Promise.then

javascript - 跨浏览器javascript下载功能

javascript - 获取 Chrome 浏览器高度或导航/菜单/工具栏高度

Angular Material 嵌套拖放

javascript - 如何在node.js中杀死child_process——req.on close

javascript - 如何在 jQuery Mobile 中等待弹出窗口关闭?

javascript - jQuery CLNDR : add div within date block

javascript - 带有 JSON 和客户端过滤数据错误的 YUI DataTable