我想构建一个HTML页面,允许用户构建一个对象,然后可以将其作为JSON发布到内部托管服务(类似于Chrome Advanced Rest Client)。用户必须能够添加和删除属性。
我的模型不正确,因为每个属性都被视为具有属性“name”和“value”的对象。我最终得到了一个对象数组,而不是具有属性的对象。
以下是HTML的摘录:
<table>
<thead>
<tr>
<th>Property Name</th>
<th>Property Value</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: myFieldList">
<tr>
<td><input data-bind="value: name" /></td>
<td><input data-bind="value: value" /></td>
<td><span class="removeVar" data-bind="click: removeProperty">Remove property</span></td>
</tr>
</tbody>
</table>
<p>
<span id="addVar" data-bind="click: addProperty">Add Property</span>
</p>
<textarea name="tasks" data-bind="value: ko.toJSON(myFieldList)"></textarea>
这是JS:
<script type="text/javascript">
function dynamicProperty(name, value) {
var self = this;
this.name = name;
this.value = value;
}
function fieldModel() {
var self = this;
//start with 2 empty properties
self.myFieldList = ko.observableArray([
new dynamicProperty("", ""),
new dynamicProperty("","")
]);
var noTracker = self.myFieldList.length;
self.removeProperty = function (dynamicProperty) {
self.myFieldList.remove(dynamicProperty);
}
self.addProperty = function () {
noTracker++;
self.myFieldList.push(new dynamicProperty(this.name,this.value));
}
}
ko.applyBindings(fieldModel);
</script>
我在textarea中得到的是这样输出:
[{"name":"test name 1","value":"test value 1"},{"name":"test name 2","value":"test value 2"}]
我想要的是这样输出:
{"test name 1":"test value 1","test name 2":"test value 2"}
我担心这是微不足道的,但在我的辩护中,我对JS和Knockout来说是一个新手,所以你能提供的任何帮助都会非常感激。感谢。
答案 0 :(得分:1)
您需要的是&#34; reducer&#34;。
一个简单的(天真的)实现就是:
function reduce(input, step, init) {
for(var i = 0; i < input.length; i++) {
init = step(init, input[i]);
}
return init;
}
然后你这样称呼它:
var in = [{"name":"test name 1","value":"test value 1"},{"name":"test name 2","value":"test value 2"}];
var out = reduce(in, function(result, item) {
result[item.name] = item.value;
return result;
}, {});
console.log(out);
它做的是它遍历你的数组并且&#34;累积&#34;单个项目中每个步骤的结果。可以是数组中数字的总和,其中&#34;累加器&#34;将是一个数字而不是一个对象。
我建议你不要自己编写,而是使用lodash,它会附带一个_.reduce
功能进行优化。
答案 1 :(得分:1)
你可能想要做这样的事情来完成它。
示例:https://jsfiddle.net/9aLvd3uw/79/
HTML
<table>
<thead>
<tr>
<th>Property Name</th>
<th>Property Value</th>
<th></th>
</tr>
</thead>
<tbody data-bind="foreach: myFieldList">
<tr>
<td><input data-bind="textInput: name" /></td>
<td><input data-bind="textInput: value" /></td>
<td><span class="removeVar" data-bind="click: removeProperty">Remove property</span></td>
</tr>
</tbody>
</table>
<p>
<span id="addVar" data-bind="click: addProperty">Add Property</span>
</p>
<textarea name="tasks" data-bind="value: myFieldList2"></textarea>
JS
function dynamicProperty(name, value) {
var self = this;
self.name = ko.observable(name || '');
self.value = ko.observable(value || '');
}
function fieldModel() {
var self = this;
self.name = ko.observable();
self.value = ko.observable();
self.myFieldList = ko.observableArray([
new dynamicProperty("test_name_1", "test value 1"),
new dynamicProperty("test_name_2","test value 2")
]);
var noTracker = self.myFieldList.length;
self.myFieldList2 = ko.computed(function () {
var string = '{';
ko.utils.arrayForEach(self.myFieldList(), function (item) {
string += item.name() + ': ' + item.value() + ',';
});
string = string.replace(/,\s*$/, "");
string+='}';
return string;
});
self.removeProperty = function (dynamicProperty) {
self.myFieldList.remove(dynamicProperty);
}
self.addProperty = function () {
noTracker++;
self.myFieldList.push(new dynamicProperty('',''));
}
}
ko.applyBindings(fieldModel);