Добавление нового значения во вложенный наблюдаемый массив, созданный с помощью плагина knockout.mapping и knockoutjs - PullRequest
0 голосов
/ 30 сентября 2011

Так близко к тому, чтобы заставить это работать как ожидалось.Я получаю данные из запроса 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/

Ответы [ 2 ]

1 голос
/ 01 октября 2011

Если вы связываетесь с 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>

1 голос
/ 30 сентября 2011

Причина, по которой вы получаете сообщение об ошибке «addPoint не определен», заключается в том, что вы находитесь внутри шаблона дочернего свойства модели представления.Внутри шаблона контекст привязки является объектом статистики, а не моделью представления.

Итог: Knockout ищет функцию stat.addPoint, которой не существует, поэтому вы получаете сообщение об ошибке.

Что вы, вероятно, хотите сделать, это сослаться на родительский связывающий контекст, вашу модель представления.В бета-версии KO 1.3 вы можете получать доступ к контекстам родительской привязки следующим образом:

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

Если вы застряли в старой версии Knockout, которая не обеспечивает доступ к родительской привязкеВ контексте, дайте мне знать, есть несколько дополнительных опций, таких как глобальная доступность вашей модели представления, а затем просто привязка к этому полностью определенному имени.

...