0

如此接近让它按预期工作。我从 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 以将点添加到单个数组。我需要找到一种方法在生成的映射中实现这一点。

http://jsfiddle.net/vv2Wx/1/

4

2 回答 2

1

您收到“未定义 addPoint”错误的原因是因为您位于视图模型的子属性的模板中。在模板内部,绑定上下文是一个 stat 对象,而不是您的视图模型。

底线:Knockout 正在寻找一个不存在的 stat.addPoint 函数,因此您会收到错误消息。

您可能想要做的是引用父绑定上下文,即您的视图模型。在 KO 1.3 beta 中,您可以像这样访问父绑定上下文

<button data-bind="click: $.parent.addPoint">Add Point</button>

如果您卡在不提供对父绑定上下文的访问的旧版本的 Knockout 上,请告诉我,还有一些其他选项,例如使您的视图模型全局可访问,然后只需绑定到该完全限定名称.

于 2011-09-30T19:59:42.870 回答
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>

于 2011-09-30T20:00:58.090 回答