Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Braintree在多个onPaymentMethodReceived事件中生成多个设置调用_Javascript_Angularjs_Braintree - Fatal编程技术网

Javascript Braintree在多个onPaymentMethodReceived事件中生成多个设置调用

Javascript Braintree在多个onPaymentMethodReceived事件中生成多个设置调用,javascript,angularjs,braintree,Javascript,Angularjs,Braintree,我使用angularUI,在angularUI模式窗口中,我想显示Braintree中的Drop-in表单,以获得付款方式。因此,我创建了通常的表单(partial.html): 其中ModalController包含对Braintree设置的调用: braintree.setup($scope.clientToken, 'dropin', { container: 'dropin', onPaymentMethodReceived: function (result) {

我使用angularUI,在angularUI模式窗口中,我想显示Braintree中的Drop-in表单,以获得付款方式。因此,我创建了通常的表单(
partial.html
):

其中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表单(安装程序生成表单),并接受信用卡和到期日期,到目前为止一切正常

问题是,每次调用modal时,都会执行ModalController,因此也会执行
braintree.setup()
。然后,当我输入信用卡号和到期日期并点击pay时,
onPaymentMethodReceived()
事件会在每次安装执行时触发一次!也就是说,如果第一次调用模态,它将触发事件一次,第二次将触发事件两次,依此类推。就像每次调用setup时,都会创建一个新的事件挂钩

有没有办法避免这种情况?是否有方法“解除”事件处理程序的绑定?我确实需要多次调用安装程序,因为每次调用modal时,clientToken都可能已更改


感谢您提供的任何帮助或指向帮助的指针。

调用
braintree.setup
在angular中多次似乎是不可避免的,这可能是由于询问者的原因,也可能仅仅是因为
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
           });
       }
   }
});

我发现我无法避免多次触发回调(每次我重新访问view-yikes时,次数似乎会爆炸),但我可以测试我是否执行了响应回调的操作。由于如果我离开视图,
$scope
将被销毁,
$scope.success
在我需要时被有效重置。由于每个新控制器都有自己的
$scope
,因此在
$scope
上设置
成功
标志可能只会停止该
$scope
上的其他执行(即使控制器已“销毁”,回调似乎仍可用),所以我发现使用
$rootScope
只意味着一次执行总数,即使我多次重新实例化了控制器。在控制器中设置
$rootScope.success=false
意味着一旦加载了控制器,回调将再次成功–一次。

我认为从那时起,它就由API通过拆卸来处理:

在某些情况下,您可能需要删除braintree.js集成。这在单页应用程序、模式流和其他状态管理是关键因素的情况下很常见。[...] 调用teardown将清除集成创建的任何DOM节点、事件处理程序、弹出窗口和/或iFrame


(我还没有试过)

Arpad Tamas提供的链接不再包含这些信息。因此,我将BrainTree提供的信息发布给子孙后代;)尤其是因为我花了几次时间才通过谷歌搜索找到它

在某些情况下,您可能需要删除Braintree.js集成。这在单页应用程序、模式流和其他状态管理是关键因素的情况下很常见。调用braintree.setup时,可以将回调附加到onReady,它将提供一个包含拆卸方法的对象

调用teardown将清除集成创建的任何DOM节点、事件处理程序、弹出窗口和/或iFrame。此外,teardown接受一个回调,您可以使用它来知道何时可以安全地继续

每个.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!
        });
    }
};

我在Braintree工作。我们正在努力改进这一点;目前还没有一个简单的解决方案。如果您需要,他们应该能够帮助您。关于此方面的任何更新,@agf?现在正确的方法是使用,在本次讨论后添加。
$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
           });
       }
   }
});
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!
});
$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!
        });
    }
};