在我的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.
有错误的上下文?
答案 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();
}
});
}