我有一个表单,我想用Knockout以正常方式提交,将它绑定到一个函数而不是访问像
这样的元素 var value = form.element
我想遍历表单元素。表单对象在访问之前似乎不包含元素,那么如何在不知道它们的id的情况下迭代它们呢?我想避免使用数字ID和for循环 以下是我的不起作用:
saveChanges: function(form) {
form.each(function( element ) {
//do something
});
表单对象的console.log()
输出是奇怪的:
{"0":{},"1":{"__ko__1429589442426":"ko66"},
"2":{"__ko__1429589442426":"ko74"},
"3":{"__ko__1429589442426":"ko79"},
"4":{},"__ko__1429589442426":"ko60"}
有什么建议吗?
编辑:为什么我需要这样做?
我的表单元素来自我的api,它是用强类型语言制作的。 '偏好'每个都有' booleanvalue',' numericvalue',' stringvalue'以及首选类型的值,或者' bool','麻木'或' stri'在调用api时,我返回所有值,然后只显示首选的一个使用knockout' s if:binding。
从api返回的示例:
[{"type":"bool","stringvalue":null,"preference":"taxable","numericvalue":"0","id":3,"booleanvalue":true},{"type":"stri","stringvalue":"Acme inc.","preference":"company_name","numericvalue":"0","id":2,"booleanvalue":false}]
当我收集表单输入onsubmit时,我需要获取首选项的名称和列名,booleanvalue,stringvalue,numericvalue。我通过设置id属性来包含信息来做到这一点,这样我就可以解析id键来获取列名,并使用该值作为列值。这是一个例子:
id= company_name.stringvalue value= "acme co."
id= taxable.booleanvalue value= "true"
id= tax_rate.numericvalue value= "0.0112"
这是在Durandal应用程序内部,所以小提琴不起作用,但你可以看到我的html / js。 https://jsfiddle.net/ggja7qv2/
我没有硬编码这些的原因是因为我将来会从api添加更多首选项,并且我希望前端能够编辑这些首选项而不必返回它并更改内容。前端应该以
的形式将JSON发送到api{"data":[{"preference":"company_name","stringvalue":"acme inc"},{"preference":"taxable","booleanvalue":"false"}]}
答案 0 :(得分:1)
使用纯粹淘汰赛解决这个问题很有趣:)
您需要的第一件事是处理您奇怪的多类型偏好的视图模型。我们称之为Preference
:
// dictionary to convert preference types to
// the properties that hold their values
var typeToValueName = {
bool: 'booleanvalue',
stri: 'stringvalue',
nume: 'numericvalue',
};
// dictionary from types to valid html input types
var typeToInputType = {
bool: 'checkbox',
stri: 'text',
nume: 'number',
};
function Preference(data) {
this.preference = data.preference;
this.valueTypeName = typeToValueName[data.type];
this.inputType = typeToInputType[data.type];
this.value = ko.observable(data[this.valueTypeName]);
// if this is a checkbox, the value is bound differently (you can make this computed if you're dynamically changing your input types)
this.isCheckbox = this.inputType === 'checkbox';
}
然后你需要将这些数组绑定到你的表单:
<form data-bind="submit: save">
<!-- ko ifnot: preferences().length -->
Loading preferences...
<!-- /ko -->
<!-- ko foreach: preferences -->
<label>
<span data-bind="text: preference"></span>
<!-- ko if: isCheckbox -->
<input data-bind="attr: {type: inputType}, checked: value"/>
<!-- /ko -->
<!-- ko ifnot: isCheckbox -->
<input data-bind="attr: {type: inputType}, value: value"/>
<!-- /ko -->
</label>
<br/>
<!-- /ko -->
<input type="submit" value="Save"></input>
</form>
最后,当您提交表单时,您需要将此数组映射到更简单的数组:
var vm = {
preferences: ko.observable([]), // no need to make this an observable array unless you're dealing with adding/removing preferences one by one.
save: function () {
console.log(this.preferences().map(function(p){
var outputFormat = { preference: p.preference };
outputFormat[p.valueTypeName] = p.value();
return outputFormat;
}));
}
};
你可以自动化上面的很多内容,但这是明确的,因此它可以帮助你开始考虑“淘汰赛方式”。祝你好运,这里有一个小小的玩法:http://jsfiddle.net/h2qq0k42/
答案 1 :(得分:1)
您可以使用jquery:
$(form).find('input')
这将返回所有表单元素。
OTOH,请不要将信息存储在ID中。您可以使用data-
属性,每个信息对应一个属性,然后以这种方式阅读它们:
$(form).find('input')[0].attr('data-booleanvalue')
生成的输入应如下所示:
<input type="...." data-booleanvalue="true" ... />