我应该如何使用angularjs处理部分表格?

时间:2013-12-30 03:32:10

标签: angularjs

我认为有人必须先遇到这种情况。基本上我有一个很大的“形式”,里面有多个较小的“形式”。 (事实上​​,它们不是真实的形式,只是将一组输入组合在一起以收集模型的信息)。

此表单适用于结帐页面,其中包含:

  1. 送货地址
  2. 送货方式
  3. 帐单邮寄地址
  4. 结算方式
  5. 其他附加信息,如折扣代码输入,礼品包装等。
  6. 我想在用户完成每个部分后立即将用户填写的信息更新到服务器(例如,当他们完成送货地址时)。但是,我想让它无缝地工作,而不需要用户在填充每个部分部分后点击某种“更新”按钮。我想知道是否有办法解决这个问题?

2 个答案:

答案 0 :(得分:0)

你需要$watch有问题的字段,并在填写时对它们采取行动(比如保存到数据库)。你将遇到的问题是如何确定用户填写字段的时间像onblur等在实践中不能很好地工作。我建议使用所谓的去抖功能,这个功能基本上是一个允许用户暂停X时间而不需要我们的代码就可以“完成的功能!现在让我们......哦等待打字......”

这是我在自己的购物车上使用的一个示例 - 我想在我有地址后自动获得运费报价,所以我看这些字段,允许暂停我的去抖功能然后调用我的服务器获取报价。

这是一些控制器代码:

// Debounce function to wait until user is done typing
function debounce(fn, delay) {
  var timer = null;
  return function() {
    var context = this,
      args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  };
}

// Apply debounce to our shipping rate fetch method
var fetch = debounce(function() {
  $scope.fetching = true;
  cartService.updateShipping($scope.shipping, function(data) {
    $scope.fetching = false;
    $scope.quotes = data;
  });
}, 1000);

// Watch the shipping fields - when enough done and user is done typing then get quote
$scope.$watch('shipping', function(newVal, oldVal) {
  // I use this to play around with what fields I actually want before I do something
  var fields = ['street', 'region', 'name', 'postal', 'country', 'city'];
  var valid = true;
  fields.forEach(function(field) {
    if (!$scope.form[field].$valid) {
      valid = false;
    }
  });
  if (valid) fetch();
}, true);

我的表单字段设置如下:

<input type="text" name="street ng-model="shipping.street" required>
<input type="text" name="name" ng-model="shipping.name" required>

请注意我如何将它们作为“送货”对象的一部分 - 这样我就可以独立于其他方式查看送货字段,例如结算。

请注意,上述内容适用于运输领域等极端情况。对于简单的事情,例如订阅时事通讯,如果他们选中了一个方框,那么您不需要使用上述内容,只需在您的复选框中进行ng-click="spamMe();"来电即可。该功能(spamMe)将在您的控制器中,然后可以调用您的服务器等...

var spamMe = function() {

  // Grab the email field that might be at top - ideally check if it's filled in but you get the idea
  var email = $scope.email;
  $http.post('/api/spam', ....);
}

答案 1 :(得分:0)

我在每个变量上应用$scope.$watch来触发一个函数,检查是否填写了给定部分的所有字段,如果是,则将其作为一个提交给服务器ajax请求。

这是我写这篇文章的尝试:

var shippingFields = ['address', 'city', 'state', 'zip']     // etc

function submitFieldsWhenComplete(section, fields) {
    fieldValues = fields.forEach(function (field) {
        return $scope[section][field]
    });

    if (fieldValues.every()) {
        // We've got all the values, submit to the server

        $http.post({
            url: "/your/ajax/endpoint",
            data: $scope.shipping
        })
    }
}

shippingFields.forEach(function(field) {
    $scope.$watch(function() {
        return $scope['shipping'][field]
    }, function(val) {
        submitFieldsWhenComplete('shipping', shippingFields);
    });
});