我认为有人必须先遇到这种情况。基本上我有一个很大的“形式”,里面有多个较小的“形式”。 (事实上,它们不是真实的形式,只是将一组输入组合在一起以收集模型的信息)。
此表单适用于结帐页面,其中包含:
我想在用户完成每个部分后立即将用户填写的信息更新到服务器(例如,当他们完成送货地址时)。但是,我想让它无缝地工作,而不需要用户在填充每个部分部分后点击某种“更新”按钮。我想知道是否有办法解决这个问题?
答案 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);
});
});