Angular Stripe - 将 Stripe 支付表单转换为 Stripe 元素

Angular Stripe - Converting Stripe Payment Form to Stripe Elements

我曾经有 Angular Stripe Checkout 表单,我正在尝试将我的表单更新为最近推出的新 Stripe Card Elements

删除表单输入字段并将其替换为条纹卡片元素后,我的表单如下所示:

<form name="payment" ng-submit="vm.submit()">
<div class="row">
    <label for="card-element">
      Credit or debit card
    </label>
    <div id="card-element">
      <!-- a Stripe Element will be inserted here. -->
    </div>
</div>
<button class="btn btn-primary" type="submit" ng-disabled="vm.submitting">Pay!</button>
<div ng-show="vm.cardError" class="row">
  <div class="has-error">
     <p class="help-block">* {{vm.cardError}}</p>
  </div>
</div>
</form>

以前在 Angular 中,提交表单时,我正在处理来自控制器的 submit()stripeResponseHandler。使用新更改更新我的 Angular 控制器后,我的控制器现在看起来像这样:

function PaymentController() {
        var vm = this;
        var elements = stripe.elements();
        var style = {
                          base: {
                            color: '#32325d',
                            lineHeight: '24px',
                            fontFamily: 'Helvetica Neue',
                            fontSmoothing: 'antialiased',
                            fontSize: '16px',
                            '::placeholder': {
                              color: '#aab7c4'
                            }
                          },
                          invalid: {
                            color: '#fa755a',
                            iconColor: '#fa755a'
                          }
                     };
        vm.card = elements.create('card', {style: style});
        vm.card.mount('#card-element');

        // Handle real-time validation errors from the card Element.
        vm.card.addEventListener('change', function(event) {
              if (event.error) {
                vm.cardError = event.error.message;
              } else {
                vm.cardError = '';
              }
        });

        function submit() {
            vm.cardError = '';
            vm.submitting = true;
            createToken();
        }

        // Send data directly to stripe 
        function createToken() {
            stripe.createToken(vm.card).then(function(result) {
              if (result.error) {
                vm.cardError = result.error.message;
                vm.submitting = false;
              } else {
                // Send the token to your server
                stripeTokenHandler(result.token);
              }
            });
        }

        // Response Handler callback to handle the response from Stripe server
        function stripeTokenHandler(token) {
            vm.tokenData = {
                token: token.id
            };
            .. Process the rest in server ...
        }
}

以上代码按原样工作。但我对这些感到困惑:

1) 由于 Stripe 现在使用 DOM 操作在表单中插入卡片元素,这是否会使我的上述方法与 Angular 方式一样错误?意思是,我是否应该不再在 Controller 中执行这些操作并将它们移至指令?或者这不是必需的,因为操作的元素正在使用 stripe.elements().

2) 如果我确实需要在指令中包含它们,我只是不确定如何将上面的内容转换为 angular 指令。它首先通过挂载元素来操作元素(可以将其添加到指令 link 函数中),但随后它继续将 card 元素用于表单提交和事件处理程序。我是否需要在指令 link 本身内执行所有这些操作,或者在指令控制器中提交并在 link 中进行元素操作?

我很困惑,不知道该怎么办。如果我做错了,有人可以给我一个示例,告诉我如何解决这个问题吗?

我正在使用 Angular 1.5.

我现在已将控制器更改为指令,并将所有 jquery 和 angular 代码放入 Link 函数中。这是更新后我的指令代码的样子:

function stripeForm() {

        // Link Function
        function link(scope, element, attrs) {

            scope.submitCard = submitCard;

            var elements = stripe.elements();
            var style = {
                          iconStyle: 'solid',
                          style: {
                            base: {
                              iconColor: '#8898AA',
                              color: '#000',
                              lineHeight: '36px',
                              fontWeight: 300,
                              fontFamily: 'Helvetica Neue',
                              fontSize: '19px',

                              '::placeholder': {
                                color: '#8898AA',
                              },
                            },
                            invalid: {
                              iconColor: '#e85746',
                              color: '#e85746',
                            }
                          },
                          classes: {
                            focus: 'is-focused',
                            empty: 'is-empty',
                          },
                        };
            var card = elements.create('card', style);
            card.mount('#card-element');

            // Handle real-time validation errors from the card Element.
            card.on('change', function(event) {
                setOutcome(event);
            });

            // Form Submit Button Click
            function submitCard() {
                var errorElement = document.querySelector('.error');
                errorElement.classList.remove('visible');
                createToken();
            }

            // Send data directly to stripe server to create a token (uses stripe.js)
            function createToken() {
                stripe.createToken(card).then(setOutcome);
            }

            // Common SetOutcome Function
            function setOutcome(result) {
                var errorElement = document.querySelector('.error');
                errorElement.classList.remove('visible');
                if (result.token) {
                  // Use the token to create a charge or a customer
                  stripeTokenHandler(result.token);
                } else if (result.error) {
                  errorElement.textContent = result.error.message;
                  errorElement.classList.add('visible');
                }
            }

            // Response Handler callback to handle the response from Stripe server
            function stripeTokenHandler(token) {
                ..send to server ...
            }
        }

        // DIRECTIVE
        return {
            restrict: 'A',
            replace: true,
            templateUrl: 'payment/PaymentForm.html'
            link: link
        }
    }

我的 HTML 文件现在是这样的:

<form ng-submit="submitCard()">
    <div>
      <label>
        <div id="card-element" class="field"></div>
      </label>
    </div>
    <div>
        <button class="btn btn-primary pull-right" type="submit">Pay!</button>
        <button class="btn btn-danger pull-left" type="button" ng-click="cancel()">Cancel</button>
    </div>
    <div>
      <div class="error"></div>
    </div>
</form>