Frage Braintree-Aufrufe mit mehreren Setups führen zu mehreren onPaymentMethodReceived-Ereignissen


Ich benutze eckig und in einem eckigen UI-modalen Fenster möchte ich das Drop-In-Formular von Braintree zeigen, um eine Zahlungsmethode zu erhalten. So erstelle ich die übliche Form (partial.html):

<form id="creditCard" >
   <div id="dropin"></div>  
   <button type="submit" id="btnPay" >Pay</button>  
</form>

und dann zeige ich das modale mit diesem:

var modalInstance = $modal.open({
   templateUrl: 'partial.html',
   controller: 'ModalController'
});

Wo ModalController den Aufruf der Braintree-Installation enthält:

braintree.setup($scope.clientToken, 'dropin', {
   container: 'dropin',
   onPaymentMethodReceived: function (result) {
       $scope.$apply(function() {
           $scope.success = true;
           // Do something else with result
       });
   }
});

Dies zeigt das Drop-In-Formular von braintree (das Setup generiert das Formular) und akzeptiert die Kreditkarte und das Ablaufdatum, alles funktioniert gut bis jetzt.

Das Problem ist, dass jedes Mal, wenn ich das Modal aufruft, der ModalController ausgeführt wird und somit der braintree.setup() wird auch ausgeführt. Dann, wenn ich die Kreditkartennummer und das Ablaufdatum eintrage und die Zahlung bezahle, wird die onPaymentMethodReceived() Ereignis wird einmal pro Setup-Ausführung ausgelöst! Das heißt, wenn ich das Modal das erste Mal aufruft, löst es das Ereignis einmal aus, das zweite Mal löst es zweimal aus und so weiter. Wie wenn jedes Mal, wenn ich Setup aufrufen, ein neuer Hook für das Ereignis erstellt wird.

Irgendeine Idee, wie man das vermeidet? Gibt es eine Möglichkeit, das "zu lösen"? onPaymentMethodReceived() Ereignishandler? Ich muss das Setup mehrmals aufrufen, da das clientToken bei jedem Aufruf des Modals geändert wurde.

Danke für jede Hilfe oder Hilfe.


10
2018-05-18 22:26


Ursprung


Antworten:


Berufung braintree.setup Ein Mehrfaches von Winkeln erscheint unvermeidlich, entweder aus Gründen des Fragestellers oder einfach deshalb setup wird in einem Controller aufgerufen, der in einer Browsersitzung mehrmals instanziiert werden kann - wie ein Einkaufswagen oder eine Kasse.

Sie können so etwas tun:

$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
           });
       }
   }
});

Ich stellte fest, dass ich nicht vermeiden konnte, dass der Callback mehrmals ausgelöst wurde (die Anzahl der Male scheint jedesmal zu explodieren, wenn ich die Ansicht erneut betrachte), aber ich konnte testen, ob ich meine Aktionen als Reaktion auf den Callback ausgeführt hatte. Seit der $scope wird zerstört, wenn ich den Blick verlasse, $scope.success wird effektiv zurückgesetzt, wenn ich es brauche. Weil jeder neue Controller seinen eigenen hat $scope, Einstellung a success Flagge auf der $scope kann nur zusätzliche Ausführungen dazu anhalten $scope (das scheint immer noch für den Rückruf verfügbar zu sein, auch wenn der Controller "zerstört" wurde), so fand ich das mit $rootScope bedeutete nur eine Ausführung insgesamt, auch wenn ich den Controller mehrmals instanziiert. Rahmen $rootScope.success = false in der Steuerung bedeutet, dass sobald der Controller geladen ist, der Rückruf von neuem erfolgreich ist - einmal.


2
2017-07-29 18:20



Ich denke, dass es von der API seitdem mit teardown gehandhabt wird:

In bestimmten Szenarien müssen Sie möglicherweise Ihre braintree.js-Integration entfernen. Dies ist bei einseitigen Anwendungen, modalen Abläufen und anderen Situationen, in denen die Zustandsverwaltung ein Schlüsselfaktor ist, üblich. [...]   Das Aufrufen von Teardown bereinigt alle DOM-Knoten, Event-Handler, Popups und / oder Iframes, die durch die Integration erstellt wurden.

https://developers.braintreepayments.com/guides/client-sdk/javascript/v2#teardown

(Ich habe es noch nicht ausprobiert)


1
2017-11-14 18:45



Der Link von Arpad Tamas enthält die Informationen nicht mehr. Also poste ich die Informationen von BrainTree für die Nachwelt;) Zumal es mich ein paar Versuche bedurfte, es bei einer Google-Suche zu finden.

In bestimmten Szenarien müssen Sie möglicherweise Ihre Braintree.js-Integration entfernen. Dies ist bei einseitigen Anwendungen, modalen Abläufen und anderen Situationen, in denen die Zustandsverwaltung ein Schlüsselfaktor ist, üblich. Wenn Sie braintree.setup aufrufen, können Sie einen Rückruf an onReady anhängen, der ein Objekt mit einer Teardown-Methode bereitstellt.

Das Aufrufen von Teardown bereinigt alle DOM-Knoten, Event-Handler, Popups und / oder Iframes, die durch die Integration erstellt wurden. Zusätzlich akzeptiert teardown einen Rückruf, mit dem Sie wissen können, wann es sicher ist, fortzufahren.

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

Sie können Teardown nur einmal pro Aufruf von .setup aufrufen. Wenn Sie während eines anderen Teardowns diese Methode aufrufen, wird ein Fehler angezeigt, der besagt, dass Teardown nicht aufgerufen werden kann. Nach dem Abschluss werden nachfolgende Teardown-Aufrufe einen Fehler mit dieser Meldung auslösen: Die Integration kann nicht mehr als einmal abgebrochen werden.

Ich habe diesen Code in eine Funktion eingepackt, die ich jedes Mal anrufe, wenn die zugehörige ionische Betrachtungsansicht eingegeben wird.

$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!
        });
    }
};

1
2018-03-07 22:04