2015-05-18 24 views
10

Tôi đang sử dụng góc cạnh và trong cửa sổ phương thức angularUI Tôi muốn hiển thị biểu mẫu thả xuống từ Braintree để nhận phương thức thanh toán. Vì vậy, tôi tạo ra các hình thức thông thường (partial.html):Thiết lập nhiều cuộc gọi thiết lập Braintree cho nhiều sự kiện trênPaymentMethodReceived

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

và sau đó tôi hiển thị các phương thức với điều này:

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

đâu ModalController chứa các cuộc gọi đến thiết lập Braintree:

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

Điều này sẽ hiển thị biểu mẫu thả xuống từ braintree độc ​​đáo (thiết lập tạo biểu mẫu) và chấp nhận thẻ tín dụng và ngày hết hạn, tất cả đều hoạt động tốt cho đến thời điểm này.

Vấn đề là, mỗi lần tôi gọi phương thức, ModalController được thực hiện, và do đó braintree.setup() cũng được thực thi. Sau đó, khi tôi nhập số thẻ tín dụng và ngày hết hạn và lần trả tiền, sự kiện onPaymentMethodReceived() được kích hoạt một lần cho mỗi lần thực hiện thiết lập! Đó là, nếu lần đầu tiên tôi gọi phương thức, nó sẽ kích hoạt sự kiện một lần, lần thứ hai nó sẽ kích hoạt nó hai lần, v.v. Giống như mỗi khi tôi gọi thiết lập, một móc mới cho sự kiện được tạo.

Bất kỳ ý tưởng nào về cách tránh điều này? Có cách nào để "unbind" xử lý sự kiện onPaymentMethodReceived()? Tôi cần phải gọi thiết lập nhiều lần vì mỗi lần tôi gọi phương thức, clientToken có thể đã thay đổi.

Cảm ơn mọi trợ giúp hoặc con trỏ để trợ giúp.

+0

Tôi làm việc tại Braintree. Chúng tôi đang làm việc để cải thiện điều này; không có một giải pháp đơn giản, tuyệt vời cho việc này vào lúc này. Nếu bạn [liên lạc với nhóm hỗ trợ của chúng tôi] (https://support.braintreepayments.com/) họ sẽ có thể giúp bạn. – agf

+1

Mọi cập nhật về điều này, @agf? –

Trả lời

2

Gọi số braintree.setup nhiều lần trong góc có vẻ không thể tránh khỏi, hoặc vì lý do của người hỏi, hoặc đơn giản là vì setup được gọi trong bộ điều khiển có thể được khởi tạo nhiều lần trong phiên duyệt web - như giỏ hàng hoặc bộ điều khiển thanh toán.

Bạn có thể làm một cái gì đó như thế này:

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

tôi thấy tôi đã không thể để tránh việc gọi lại lửa nhiều lần (số lần dường như nổ tung mỗi khi tôi xem lại quan điểm - yikes) , nhưng tôi có thể kiểm tra xem tôi đã thực hiện hành động của mình để đáp lại lời gọi lại chưa. $scope sẽ bị hủy nếu tôi rời khỏi chế độ xem, $scope.success được đặt lại hiệu quả khi tôi cần. Vì mỗi bộ điều khiển mới sẽ có $scope riêng, đặt cờ success trên $scope chỉ có thể tạm dừng thực thi bổ sung trên $scope đó (dường như vẫn có sẵn cho cuộc gọi lại, ngay cả khi bộ điều khiển đã bị "hủy"), vì vậy tôi thấy rằng việc sử dụng $rootScope chỉ có nghĩa là một tổng số thực thi, ngay cả khi tôi đã khởi tạo lại bộ điều khiển nhiều lần. Đặt $rootScope.success = false trong bộ điều khiển có nghĩa là khi bộ điều khiển được tải, cuộc gọi lại sẽ thành công một lần nữa.

+0

Cách đúng để thực hiện điều này ngay bây giờ là với phương pháp [teardown'] (https://developers.braintreepayments.com/reference/client-reference/javascript/v2/best-practices#teardown), được thêm vào sau cuộc thảo luận này. –

1

Tôi nghĩ rằng nó xử lý bởi các API kể từ đó với teardown:

Trong một số tình huống bạn có thể cần phải loại bỏ hội nhập braintree.js bạn. Điều này là phổ biến trong các ứng dụng trang đơn, luồng phương thức và các tình huống khác mà quản lý nhà nước là yếu tố quan trọng. [...] Gọi teardown sẽ dọn sạch mọi nút DOM, trình xử lý sự kiện, cửa sổ bật lên và/hoặc iframe đã được tạo bởi tích hợp.

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

(Tôi đã không thử nó chưa)

1

Các liên kết đưa ra bởi Arpad Tamas không chứa các thông tin nữa. Vì vậy, tôi đăng các thông tin được đưa ra bởi BrainTree cho hậu thế;) Đặc biệt là kể từ khi nó đã cho tôi một vài cố gắng để tìm thấy nó với một tìm kiếm của Google.

Trong một số tình huống bạn có thể cần phải xóa mã tích hợp Braintree.js của bạn. Điều này là phổ biến trong các ứng dụng trang đơn, luồng phương thức và các tình huống khác mà quản lý nhà nước là yếu tố quan trọng. Khi gọi braintree.setup, bạn có thể đính kèm một cuộc gọi lại đến onReady, nó sẽ cung cấp một đối tượng có chứa một phương thức teardown.

Gọi teardown sẽ dọn sạch mọi nút DOM, trình xử lý sự kiện, cửa sổ bật lên và/hoặc iframe đã được tạo bởi tích hợp. Ngoài ra, teardown chấp nhận một cuộc gọi lại mà bạn có thể sử dụng để biết khi nào thì an toàn để tiếp tục.

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

Bạn chỉ có thể gọi teardown một lần cho mỗi cuộc gọi .setup. Nếu bạn tình cờ gọi phương thức này trong khi đang tiến hành teardown khác, bạn sẽ nhận được thông báo lỗi Không thể gọi teardown khi đang tiến hành. Sau khi hoàn thành, các cuộc gọi tiếp theo để teardown sẽ ném một lỗi với thông báo này: Không thể teardown hội nhập nhiều hơn một lần.

Tôi đã bọc mã này trong một hàm mà tôi gọi là mỗi lần xem ion thanh toán liên quan được nhập vào.

$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! 
     }); 
    } 
}; 
Các vấn đề liên quan