如此接近让它按预期工作。我从JSON请求获取数据,然后使用映射插件映射它。我想在点击绑定上为嵌套数组添加新值。
现在我的代码中出现了一个错误,即addPoint未定义。
查看:
<table>
<tbody data-bind='template: {name: "statRowTemplate", foreach: stats }'></tbody>
</table>
<script id="statRowTemplate" type="text/html">
{{if type() != "column"}}
<tr>
<td><label>Name: </label><input data-bind="value: name" /></td>
<td>
<label>Plot Points: </label><ul class="list-plot-points" data-bind="template: {name: 'dataTemplate' , foreach: data}"></ul>
<button data-bind="click: addPoint">Add Point</button>
</td>
</tr>
{{/if}}
</script>
<script type="text/html" id="dataTemplate">
<li>
<input data-bind="value: val" />
</li>
</script>
<button data-bind="click: saveChanges">Save Changes</button>
查看模型
var viewModel = {};
$.getJSON('data-forecast-accuracy.json', function(result) {
function mappedData(data) {
this.val = data;
}
//override toJSON to turn it back into a single val
mappedData.prototype.toJSON = function() {
return parseInt(ko.utils.unwrapObservable(this.val), 10); //parseInt if you want or not
};
var mapping = {
'data': {
create: function(options) {
return new mappedData(options.data)
}
}
}
viewModel.stats = ko.mapping.fromJS(result, mapping);
viewModel.addPoint = function() {
this.stats.data.push(new mappedData(0));
}
viewModel.saveChanges = function() {
var unmapped = ko.mapping.toJSON(viewModel.stats);
//console.log(unmapped);
$.post('save-changes.php', {data: unmapped})
.success(function(results) { console.log("success")})
.error(function() { console.log("error"); })
.complete(function() { console.log("complete"); });
}
ko.applyBindings(viewModel);
});
JSON:
[{"type":"spline","marker":{"symbol":"diamond"},"name":"Cumulative","data":[10,17,18,18,16,17,18,19]},{"type":"spline","marker":{"symbol":"circle"},"name":"Monthly","data":[10,22,20,19,8,20,25,23]}]
我能够从之前的响应中调整此jsfiddle以向单个数组添加点。我需要找到一种方法来在生成的映射中实现它。
答案 0 :(得分:1)
您收到“addPoint is not defined”错误的原因是因为您位于视图模型的子属性的模板中。在模板内部,绑定上下文是一个stat对象,而不是您的视图模型。
底线:Knockout正在寻找一个不存在的stat.addPoint函数,因此您会收到错误。
您可能想要做的是引用父绑定上下文,您的视图模型。在KO 1.3 beta中,您可以access parent binding contexts这样:
<button data-bind="click: $.parent.addPoint">Add Point</button>
如果您遇到了不能提供对父绑定上下文的访问的旧版Knockout,请告诉我,还有一些其他选项,例如使您的视图模型可全局访问,然后只绑定到完全限定名称。
答案 1 :(得分:1)
如果您对addPoint
具有约束力,则上下文是stats
中的项目,而不是您的视图模型。
如果viewModel
具有全局范围,则可以执行:click: viewModel.addPoint
。您需要确保在this
方法中正确设置addPoint
。最简单的方法是将方法绑定到viewModel变量,如:
viewModel.addPoint = function() {
this.stats.data.push(new mappedData(0));
}.bind(viewModel);
如果viewModel
没有全局范围,那么您可以通过templateOptions传递它。这就像:
<tbody data-bind='template: {name: "statRowTemplate",
foreach: stats, templateOptions: { add: addPoints } }'></tbody>
然后,将其称为:<button data-bind="click: $item.add">Add Point</button>
最后,如果您使用KO 1.3 beta,则可以执行:<button data-bind="click: $root.addPoint">Add Point</button>