【问题标题】:How to submit a second form only after other form is successfully submitted如何在其他表单成功提交后才提交第二个表单
【发布时间】:2015-11-16 00:50:08
【问题描述】:

我将 Angular 与 UI 路由器和 Firebase 一起使用。单个页面上有两种不同状态的两种表格:联系表格和信用卡表格。

当用户点击提交时,信用卡信息被提交给 Stripe。然后将联系表单提交给 Firebase,但前提是信用卡交易成功完成。以下代码在开发中有效。但是当代码被缩小时,联系表单永远不会提交。

对我做错了什么有什么想法吗?

联系表格的控制器:

.controller('ContactFormCtrl', ['$scope', 'Contacts', 'serviceB',  function ($scope, Contacts, serviceB) {
  var contactForm = this;
  var stripeDone = serviceB.get();
  contactForm.contact = {};
  contactForm.contacts = Contacts;

  $scope.$watch(serviceB.get, function(stripeDone) {
    if (stripeDone === 'yes') {
      console.log(contactForm.contact);
      Contacts.$add(contactForm.contact)
 } else {
      console.log('Card not charged');
       }
 }])

信用卡表单控制器:

.controller('PaymentFormCtrl', ['$scope', '$http', 'serviceB', function ($scope, $http, serviceB) {

    $scope.handleStripe = function (status, response) {

    var stripeDone='yes';

        return $http.post(http://localhost:9000/api/payments, JSON.stringify(response))
       .then(function() {
         serviceB.set(stripeDone);console.log('serviceB set now',stripeDone);})
       .then(function() {$scope.payment={};
       })
       .then(function() {$state.go('thankyou');})
}]);

ServiceB 服务:

(function() {

  'use strict';
   angular.module('App')

  // ServiceB confirms that credit card info was submitted to Stripe
    .service('serviceB', serviceB);

    function serviceB () {

        var status = null;
        return {
           get: function () {
              return status;
      },
           set: function (value) {
              status = value;
    }
   };
   }
  })();

联系工厂:

(function() {
  'use strict';

  angular.module('contacts.fact', [])

  .factory('Contacts', ['$firebaseArray', '$q', 'FBURL', 'Auth', 'Ref', function ($firebaseArray, $q, FBURL, Auth, Ref) {

      var authData = Ref.getAuth();
      var ref = new Firebase(FBURL + '/contacts/' + authData.uid);
      return $firebaseArray(ref);
    }]);
})();

路由器信息:

.state('payment.details', {
      url: '/details',
      views: {

         'top': {
            templateUrl: 'app/views/contact-form.html',
            controller: 'ContactFormCtrl as contactForm'

       },
         'bottom': {

            templateUrl: 'app/views/credit-card.html',
            controller: 'PaymentFormCtrl'
    // Note: not using controllerAs syntax because Angular Payments module does not support it
    },
     }
 })

更新:如果我将.then(function() {$state.go('thankyou');}) 从信用卡表单的控制器中移出,并将其放在联系人表单控制器中Contacts.$add(contactForm.contact) 的末尾,那么一切正常。这解决了问题,但我怀疑这是正确的解决方案。有什么想法吗?

【问题讨论】:

  • 听起来您在 ContactFormCtrl 中的 $watch 有问题。控制台日志在缩小时是否打印任何内容?如果不是,则 serviceB.get 位出现问题。
  • @KumarM 感谢您的意见。不,contactFormCtrl 中的console.log() 不打印任何内容。我想我在那里的 $watch 做错了什么,但不知道是什么。
  • $scope.$watch(serviceB.get, 应该改为 $scope.$watch(serviceB.get(),
  • @Kato 我按照您上面的建议修改了代码,但仍然没有运气。
  • 当你说它在缩小时不起作用,究竟是什么错误?

标签: angularjs firebase angularfire angular-ui-router


【解决方案1】:

看到您的最小化代码实际上会很有趣。

不缩小时,函数的stripeDone参数隐藏,局部变量stripeDone。因此,您正在评估 if 条件中 serviceB.get() 的值。

可能发生的情况是,在缩小时,缩小器没有得到参数 stripeDone 隐藏局部变量,并将 if 中的局部变量 stripeDone 和 stripeDone 缩小到相同的标识符和函数的参数 stripeDone到另一个参数。所以在最小化的情况下,你真正要做的是评估值不变的局部变量(null)而不是新值(yes)。

你为什么不直接删除这一行?

var stripeDone = serviceB.get();

只是一个假设......

【讨论】:

    【解决方案2】:

    我的怀疑是被监视的表达式: serviceB.get 在代码缩小时搞砸了

    $scope.$watch(serviceB.get
    

    而且,从服务中寻找变化的想法对我来说似乎很尴尬。为什么不让信用控制器在完成处理并且联系控制器可以监听该事件后广播事件?

    在信用控制器中,收到来自发布请求的响应后

    function {
       serviceB.set(stripeDone);
       $rootScope.$broadcast("stripeDone");
       console.log('serviceB set now',stripeDone);
    }
    

    在联系人控制器中:

    $scope.$on("stripDone", function() {
        //process
    });
    

    【讨论】:

    • 谢谢你,我会试试你的建议。但是,您知道为什么这款手表在本地服务而不是缩小时可以完美运行吗?
    • 对不起,我也不确定,我怀疑是缩小弄乱了函数名,但需要检查你的缩小代码以确保
    猜你喜欢
    • 2023-03-11
    • 2016-11-10
    • 2017-11-17
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 2023-03-16
    • 2018-08-25
    • 1970-01-01
    相关资源
    最近更新 更多