Angular 4中PayPal onAuthorize内调用外部函数报错解决咨询
这个错误的核心原因是**this的上下文指向问题**:你在onAuthorize里用了普通的function()声明,这里面的this指向的是PayPal按钮的上下文,而不是你的Angular组件实例,所以自然找不到组件里的http服务。
下面是两种可行的解决办法,同时也能帮你顺利调用自定义外部函数:
方法1:使用箭头函数(推荐)
箭头函数不会绑定自己的this,它会继承外层上下文的this(也就是你的组件实例),这样就能直接访问this.http和组件里的其他方法了。
修改后的onAuthorize部分代码如下:
onAuthorize: (data, actions) => { return actions.payment.execute().then((payment) => { const formdata: FormData = new FormData; formdata.append('Payment[trns_id]', payment.id); formdata.append('Payment[paypal]', JSON.stringify(payment)); // 注意:对象转JSON字符串才能被FormData正确传递 formdata.append('Payment[amount]', payment.transactions[0].amount.total); formdata.append('Payment[order_id]', this.order_id); // 直接访问组件属性 formdata.append('Payment[state]', payment.state); formdata.append('Payment[auth_token]', this.auth_token); // 正常调用http服务,也能直接调用组件内的自定义函数 this.http.post(environment.apiUrl + 'orders/paypal-checkout', formdata).subscribe( (result) => { this.responceData = result.json(); if (this.responceData.data.status === true && this.responceData.data.status_message === 'success') { this.router.navigateByUrl('/questionnaire/successfully'); } // 比如调用自定义的支付成功处理函数 this.handlePaymentSuccess(payment); }, (err) => { console.log('Error' + err); // 调用自定义错误处理函数 this.handlePaymentError(err); } ) }) },
方法2:提前保存组件的this引用
如果更习惯用普通函数写法,可以在PayPal按钮渲染前把组件的this存到一个变量里,比如self,然后在函数内部用self代替this:
ngAfterViewInit(): void { const total = this.total_amount; const selected_package = this.selected_package.name; const self = this; // 保存组件的this引用 this.loadExternalScript('https://www.paypalobjects.com/api/checkout.js').then(() => { paypal.Button.render({ // ...其他配置保持不变 onAuthorize: function (data, actions) { return actions.payment.execute().then(function (payment) { const formdata: FormData = new FormData; // 所有访问组件属性/方法的地方都用self代替this formdata.append('Payment[order_id]', self.order_id); formdata.append('Payment[auth_token]', self.auth_token); self.http.post(environment.apiUrl + 'orders/paypal-checkout', formdata).subscribe( (result) => { self.responceData = result.json(); if (self.responceData.data.status === true && self.responceData.data.status_message === 'success') { self.router.navigateByUrl('/questionnaire/successfully'); } // 调用自定义外部函数 self.customPaymentCallback(payment); }, (err) => { console.log('Error' + err); self.handlePaymentError(err); } ) }) }, // ...其他配置 }, '#paypal-button'); }); }
另外补充一个小细节:你之前直接把payment对象append到FormData里,后端大概率无法正确解析这个对象,建议用JSON.stringify(payment)转成字符串后再传递。
内容的提问来源于stack exchange,提问作者khurshed alam
相关产品推荐
相关产品推荐

