我正在使用角度,在angularUI模式窗口中,我想显示Braintree的Drop In表单以获取付款方式。因此,我创建了通常的表单(partial.html
):
<form id="creditCard" >
<div id="dropin"></div>
<button type="submit" id="btnPay" >Pay</button>
</form>
然后我用这个显示模态:
var modalInstance = $modal.open({
templateUrl: 'partial.html',
controller: 'ModalController'
});
ModalController包含对Braintree设置的调用:
braintree.setup($scope.clientToken, 'dropin', {
container: 'dropin',
onPaymentMethodReceived: function (result) {
$scope.$apply(function() {
$scope.success = true;
// Do something else with result
});
}
});
这将很好地显示braintree的Drop In表单(设置生成表单)并接受信用卡和到期日期,到目前为止一切正常。
问题是,每次调用模态时,都会执行ModalController,因此也会执行braintree.setup()
。然后,当我输入信用卡号码和到期日期并点击付款时,每次设置执行都会触发onPaymentMethodReceived()
事件!也就是说,如果我第一次调用模态,它将触发事件一次,第二次触发它两次,依此类推。就像每次调用setup时一样,会创建一个新的事件挂钩。
有关如何避免这种情况的任何想法?有没有办法“解除绑定”onPaymentMethodReceived()
事件处理程序?我需要多次调用设置,因为每次调用模态时,clientToken可能已经更改。
感谢您提供任何帮助或指示帮助。
答案 0 :(得分:2)
以角度多次调用braintree.setup
似乎是不可避免的,无论是出于提问者的原因,还是仅仅因为在可能在浏览会话中多次实例化的控制器中调用setup
- 如购物车或结账控制器。
您可以这样做:
$rootScope.success = false;
braintree.setup($scope.clientToken, 'dropin', {
container: 'dropin',
onPaymentMethodReceived: function (result) {
if(!$rootScope.success) {
$scope.$apply(function() {
$rootScope.success = true;
// Do something else with result
});
}
}
});
我发现我无法避免多次回调发射(每次重新访问视图时,次数似乎都会爆炸 - 但是我可以测试我是否已经执行了我的操作以响应打回来。 由于因为每个新控制器都有自己的$scope
将在我离开视图时被销毁,$scope.success
会在我需要时被有效重置。$scope
},在success
上设置$scope
标志可能只会暂停$scope
上的其他执行(即使控制器已被“销毁”,这似乎仍然可用于回调) ,所以我发现使用$rootScope
只意味着一个执行总数,即使我多次重新实例化控制器。在控制器中设置$rootScope.success = false
意味着一旦加载控制器,回调将重新成功 - 一次。
答案 1 :(得分:1)
我认为它是由API处理掉的,然后是拆解:
在某些情况下,您可能需要删除braintree.js集成。这在单页面应用程序,模态流程以及其中状态管理是关键因素的其他情况下很常见。 [...] 调用拆解将清除由集成创建的任何DOM节点,事件处理程序,弹出窗口和/或iframe。
https://developers.braintreepayments.com/guides/client-sdk/javascript/v2#teardown
(我还没试过)
答案 2 :(得分:1)
Arpad Tamas提供的链接不再包含该信息。所以我发布了BrainTree为后人提供的信息;)特别是因为我花了几次尝试用谷歌搜索找到它。
在某些情况下,您可能需要删除Braintree.js集成。这在单页面应用程序,模态流程以及其中状态管理是关键因素的其他情况下很常见。调用braintree.setup时,可以将回调附加到onReady,它将提供包含拆卸方法的对象。
调用拆除将清除由集成创建的所有DOM节点,事件处理程序,弹出窗口和/或iframe。此外,拆解接受回调,您可以使用回调来确定何时可以安全继续。
var checkout;
braintree.setup('CLIENT_TOKEN_FROM_SERVER', 'dropin', {
onReady: function (integration) {
checkout = integration;
}
});
// When you are ready to tear down your integration
checkout.teardown(function () {
checkout = null;
// braintree.setup can safely be run again!
});
每次.setup调用只能调用一次拆解。如果您在正在进行另一次拆解时碰巧调用此方法,则会收到错误消息,指出在进行中无法调用拆卸。完成后,后续的拆解调用将在此消息中引发错误:无法多次拆除集成。
我已将此代码包装在每次输入相关结帐离子视图时调用的函数中。
$scope.$on('$ionicView.enter', function() {
ctrl.setBraintree(CLIENT_TOKEN_FROM_SERVER);
});
var checkout;
ctrl.setBrainTree = function (token) {
braintree.setup(token, "dropin", {
container: "dropin-container",
onReady: function (integration) {
checkout = integration;
$scope.$emit('BTReady');
},
onPaymentMethodReceived: function(result) {
...
},
onError: function(type) {
...
}
});
// Prevents a call to checkout when entering the view for the first time (not initialized yet).
if (checkout) {
// When you are ready to tear down your integration
checkout.teardown(function () {
checkout = null; // braintree.setup can safely be run again!
});
}
};