我在表单处理中使用Struts 2 <s:checkbox />
,以及AngularJS和jQuery。
在提交之前,我需要验证,直到现在我们在项目中执行此操作:
当我们按下提交按钮时,此功能被称为:
$scope.processForm('myForm', '<s:url value="/form/validate.action" />',
'<s:url value="/form/save.action" />');
,其中processForm(formId, validateUrl, submitUrl)
是我们定义的函数:
$scope.processForm = function(form, validateUrl, submitUrl) {
window.scroll(0,0);
ProccessFormService.processStandarForm(form, validateUrl, submitUrl);
};
此外,我们在全球服务中定义了processStandarForm()
:
angular.module('ourApp').controller('myFormCtrl',
function($scope, $modal, ProccessFormService) {
...
}
在服务中:
(function() {
angular.module('ourApp').factory('ProccessFormService', ['$http', function($http) {
processStandarForm: function(form, validateUrl, submitUrl) {
this.processForm(form, validateUrl, submitUrl);
},
processForm: function(form, validateUrl, submitUrl, success) {
if ((typeof form) == 'string') {
form = document.getElementById(form);
}
var data = this.form2Object(form);
var ctrl = this;
if (data) {
if (validateUrl) {
$http({
method : 'POST',
url : validateUrl,
data : $.param(data), // pass in data as strings
headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
// set the headers so angular passing info as form data (not request payload)
}).success(function() {
if (!success) {
form.action = submitUrl;
form.submit();
} else {
ctrl.submitAjaxForm(submitUrl, data, success)
}
});
} else if (submitUrl) {
if (!success) {
form.action = submitUrl;
form.submit();
} else {
this.submitAjaxForm(submitUrl, data, success)
}
}
}
},
}
基本上,我们提交两次表单,首先进行验证,然后提交。
我不明白的是,如果我在动作类中调试,在validate()
的函数中,<s:checkbox />
的布尔值总是为真,但在{{1函数,布尔值正确提交,根据它们被选中/未选中。复选框是这样的:
submit()
据我所知,<div class="col-sm-12 form-checkbox">
<s:checkbox name = "myForm.married"
ng-model = "checkboxModel"
value = "<s:property value='%{myForm.married}'/>"
ng-change = "submitCheckbox();"
ng-init = "checkboxModel= %{myForm.married}"
theme = "simple"
ng-disabled = "anotherFunction()" />
</div>
中提交的值为fieldValue="xxx"
,默认情况下为true。所以我这样做是为了在页面加载之前更改每个<s:checkbox />
的{{1}}。虽然所有脚本都已执行,但没有任何改变。我在验证中仍然是真的。
fieldValue
那么,我怎样才能获得正确的checkbox
值,不仅可以提交,还可以进行验证? Angular服务是否被错误地写了?我真的很怀疑,但我无法弄清楚这个问题。
答案 0 :(得分:0)
你可能已经删除了(或搞砸了:uncheckedValue=true
)拦截器堆栈中有用的东西,比如https://github.com/joelittlejohn/jsonschema2pojo:
org.apache.struts2.interceptor.CheckboxInterceptor
在 defaultStack。它检查提交给操作的每个表单参数 如果它找到前缀为_checkbox
的那个,则为其插入一个值 一个参数,其名称从_checkbox的后缀派生而来 不存在。插入的默认值为false,但这可以是 通过在拦截器上设置uncheckedValue参数来更改。这意味着复选框可以附带隐藏输入 相同的名称,但前缀为
_checkbox
,以便复选框不是。{ 在表单上检查操作仍然会收到一个值而不是 未提供未选中值的默认HTML操作 复选框。
答案 1 :(得分:0)
怀疑与data
一起使用的$http()
未正确序列化。
如果要模仿jQuery中使用的$.param()
,则应使用内置序列化程序$httpParamSerializerJQLike
。
替代
$http
params序列化程序,它遵循jQuery的param()
方法逻辑。序列化程序还将按字母顺序对params进行排序。要将其用于序列化
$http
请求参数,请将其设置为paramSerializer
财产:$http({ url: myUrl, method: 'GET', params: myParams, paramSerializer: '$httpParamSerializerJQLike' });
也可以将其设置为默认
paramSerialize
r$httpProvider
。此外,您可以注入序列化程序并明确使用它 序列化表单数据以提交的示例:
.controller(function($http, $httpParamSerializerJQLike) { //... $http({ url: myUrl, method: 'POST', data: $httpParamSerializerJQLike(myData), headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); });
您可以在Convert $.param in angularjs
中找到另一种从$.param
转换为角度的方法
答案 2 :(得分:0)
我自己已经找到了问题。它在这里:
query:{"more_like_this":{"fields":[field1,field2],"like":"elastic kabana","boost_terms":3.0}}
注意var data = this.form2Object(form);
是另一个函数,我更多地挖掘了这个函数,发现这个函数正在序列化表单,手动将其转换为对象,而不是正确处理form2Object(form)
。
<input type="checkbox" />
所以我把它改成了这个:
form2Object: function(form) {
var data = null;
if ((typeof form) == 'string') {
form = document.getElementById(form);
}
if (form) {
data = new Object();
for (var i = 0; i < form.elements.length; i++) {
if ( (form.elements[i].tagName.toUpperCase() == 'INPUT') || form.elements[i].tagName.toUpperCase() == 'TEXTAREA') {
//here it considers `<input type="checkbox" />` as normal `<input />`, and will submit its `value=xxx` in validation, and it will always be `true` due to `<s:checkbox />`.
//But it will be correct in real submission because before that, we don't go through here.
data[form.elements[i].name] = form.elements[i].value;
} else if (form.elements[i].tagName.toUpperCase() == 'SELECT') {
data[form.elements[i].name] = form.elements[i].value;
}
}
}
return data;
}
但是,阅读@Roman C的回答,我意识到使用内置函数序列化表单可能会更好。所以我接受了他的回答。