繁体   English   中英

如何使用AngularJS指令从表单发送带有所有参数的POST请求?

[英]How do I send a POST request with all parameters from a form using an AngularJS directive?

我制作了一个通过指令集成Stripe的AngularJS表单。 在这里提琴: https : //jsfiddle.net/u5h1uece/

HTML:

<body ng-app="angularjs-starter">
  <script src="https://js.stripe.com/v3/"></script>
  <div ng-controller="MainCtrl">
    <form name="regForm" id="register-form">
      <label>Mail</label>
      <input ng-model="reg.email" type="email" name="username">
      <div stripe-validator 
           stripe-complete="stripeCompleted" 
           stripe-form-id="register-form"></div>
      <br>
      <button ng-model="reg.btn" ng-disabled="stripeCompleted === false || !regForm.username.$valid">Register</button>
    </form>
  </div>
</body>

JS:

var app = angular.module('angularjs-starter', []);

app.controller('MainCtrl', function($scope, $rootScope) {
  //Init stripe state via controller
  $scope.stripeCompleted = false;
});


app.directive('stripeValidator', function() {
  return {
    restrict: 'A',
    template: `
      <div id="stripe-wrapper">
        <div id="card-element"></div>
      </div>
      <small id="card-errors" class="text-danger" role="alert">{{ ccErrMsg }}</small>
      <input type="hidden" name="stripeToken" ng-value="stripeToken" />`,
    scope: {
      "stripeComplete": '=',
      "stripeFormId": '@',
      "stripeError": '=',
      "stripeToken": '=',
    },
    link: function(scope, element, attrs) {

      //Init
      var stripe = Stripe("pk_test_6pRNASCoBOKtIshFeQd4XMUh");
      var elements = stripe.elements();
      var card = elements.create("card");
      var form = document.getElementById(scope.stripeFormId);

      //mount card element https://stripe.com/docs/stripe-js/reference#element-mount
      card.mount("#card-element");

      //add event listener
      card.addEventListener('change', function(event) {

        //check for errors
        if (event.error) {
          scope.ccErrMsg = event.error.message;
        } else {
          scope.ccErrMsg = '';
        }

        //check for complete
        scope.stripeComplete = event.complete ? true : false;

        //apply scope
        scope.$apply();
      });

      //inject form submit event
      form.addEventListener("submit", function(event) {

        //prevent form submit
        event.preventDefault();

        //handle token, handle error and form submit forward
        stripe.createToken(card).then(function(result) {

          if (result.error) {
             scope.ccErrMsg = event.error.message;
             scope.stripeToken = '';
          } else {
             scope.ccErrMsg = '';
             scope.stripeToken = result.token;
          }

          //apply scope
          scope.$apply();

          //forward submit
          form.submit();
        })
      });
    }
  }
});

我不想使用form.submit() ,而是要使用$http.post()将表单参数和数据发送到我的后端,然后在.then()函数中从那里发送回任何数据。 在这种情况下,参数包括reg.email的值。

如何使用我的表单设置方式来做到这一点? 我更喜欢使用ng-submit ,但是如果那不可能,还有另一种方法吗?

我建议使用一个component来包装条纹输入。 您可以使该组件与ng-model指令一起使用,以将card元素传递回父范围,并将表单验证应用于stripe字段。

TL; DR- 这是一个小提琴的例子

您要做的第一件事是将条纹对象创建为服务,以便可以共享它。

app.service('stripe', function () {
    return Stripe("pk_test_6pRNASCoBOKtIshFeQd4XMUh");
});

然后,您可以实现Stripe component以包装Stripe输入并应用自定义ng-model验证。

app.component('stripe', {
    bindings: {
        state: '='
    },
    require: {
        model: 'ngModel'
    },
    controller: function ($element, $timeout, stripe) {
        this.$onInit = function () {
            var ctrl = this;

            // stripe is passed in to controller as a service
            var elements = stripe.elements();
            var card = elements.create('card');
            card.mount($element[0]);

            card.addEventListener('change', function (event) {
                // Attach the event as the state so it is visible
                // to consumers of the stripe component.
                ctrl.state = event;

                // Set the validity of the stripe on the ng-model
                ctrl.model.$setValidity('stripe', event.complete);

                // If the stripe is complete set the card element on 
                // the ng-model, otherwise null out the model value.
                if (event.complete) {
                    ctrl.model.$setViewValue(card);
                } else {
                    ctrl.model.$setViewValue(null);
                }
            });
        }
    }
});

然后,在主控制器中,您可以在提交表单之前创建带区令牌,然后再发送HTTP请求。

app.controller('MainCtrl', function ($scope, $http, stripe) {
    $scope.reg = {};
    $scope.onChange = function() {
        console.log($scope.card);
    };
    $scope.register = function () {
        // Create the stripe token and send the registration
        stripe.createToken($scope.card).then(function (result) {
            if (result.error) {
                console.error(result.error);
            } else {
                $scope.reg.stripeToken = result.token;
                $http.post('request-url', $scope.reg).then(function (response) {
                    console.log(response);
                }).catch(function (err) {
                    console.error(err);
                });
            }
        });
    };
});

现在,您可以简单地将stripe元素添加到模板中,如下所示:

<div ng-app="angularjs-starter" ng-controller="MainCtrl">
  <form name="regForm" id="register-form" ng-submit="register()">
    <stripe name="card" ng-model="card" state="cardState" ng-change="onChange()" ng-required="true"></stripe>
    <button ng-disabled="regForm.$invalid">Register</button>
    <span ng-if="regForm.card.$invalid">{{ cardState.error.message }}</span>
  </form>
</div>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM