KnockoutJS: преобразование массива в observableArray - PullRequest
1 голос
/ 18 марта 2011

Этот вопрос основан на KnockoutJS: щелчки в меню отслеживания и KnockoutJS: объект события . Я немного переработал код, чтобы разделить viewModel и логику пользовательского интерфейса. Сейчас я пытаюсь преобразовать массив объектов «Дети» каждого объекта «Меню» в массив observableArray, чтобы я мог добавлять / удалять дочерние элементы меню, чтобы изменить свой пользовательский интерфейс.

Вот мой упрощенный код:

var viewModel = {};
var viewContext = {
    initialize: function (data) {
        viewModel = data;

        //for (var i = 0; i < viewModel.Panels.length; i++) {
            viewContext.observe(viewModel.Panels[0].Menu);
        //}
        viewModel.menuActive = ko.observable(false);
        viewModel.currentMenu = ko.observable(0);
        viewModel.currentNode = ko.observable({});
        viewModel.currentList = ko.observableArray([])
    },
    observe: function (data) {
        for (var i = 0; i < data.Children.length; i++) {
            viewContext.observe(data.Children[i]);
        }
        data.Children = ko.observableArray(data.Children);
    },
    nodeClicked: function (event) {
        var target = $(event.target)
        var data = target.tmplItem().data

        viewContext.getData(data, function (response) {
            viewModel.currentList(response.d);
            data.Children(response.d);
        });
        viewModel.currentNode(data);
    },
    getData: function (data, onSuccess) {
        $.ajax({
            url: 'console.asmx/' + data.Method,
            type: "POST",
            cache: false,
            contentType: "application/json; charset=utf-8",
            data: ko.utils.stringifyJson(data),
            dataType: "json",
            success: onSuccess,
            error: function () {
                viewModel.currentList([]);
            }
        });
    }
};
$(function () {
    $.ajax({
        url: 'console.asmx/Initialize',
        type: "POST",
        cache: false,
        contentType: "application/json; charset=utf-8",
        data: "{}",
        dataType: "json",
        success: function (data) {
            viewContext.initialize(data.d);
            ko.applyBindings(viewModel);
        }
    });
});

Когда страница изначально отображается (с использованием шаблонов в ссылочных вопросах), все в порядке. Однако, когда я щелкаю по меню, которое вызывает событие «nodeClicked», я получаю сообщение об ошибке в строке data.Children(response.d);, которое говорит «Uncaught ReferenceError: Children is notfined» .

Я предполагаю, что строка data.Children = ko.observableArray(data.Children); неправильно преобразовывает мой массив в массив observableArray.

Любые идеи будут высоко оценены.

1 Ответ

3 голосов
/ 19 марта 2011

Можно создать массив observableArray из массива с синтаксисом, который вы используете. Это не должно вызывать проблемы. Я бы попытался записать данные и response.d в ваш обратный вызов из вашего запроса AJAX, чтобы убедиться, что они соответствуют вашим ожиданиям. Некоторые вызовы console.log, если вы используете Firefox с Firebug или Chrome, вероятно, помогут. В противном случае, даже некоторое предупреждение (ko.toJSON (data)) в обратном вызове, мы надеемся, что-то покажет. Если он говорит, что Children не определен, то это больше, чем проблема с перемещением его из обычного массива в observableArray, поскольку Chidren там вообще нет.

Вот фрагмент того, что будет и не будет работать:

$.getJSON("http://localhost/getMoreData", function (allData) {
  if (allData) {
    var mappedData = $.map(allData.rows, function (row) {
      return new Object();
    });

    // DOES NOT WORK:
    //self.koArray().unshift(mappedData);

    // DOES WORK!
    for (var i = 0; i < mappedData.length; i++) {
      self.koArray().unshift(mappedData[i]);
    }
  }
});
...