KnockoutJS:将数组转换为observableArray

时间:2011-03-18 14:42:46

标签: knockout.js jquery-templates

此问题在KnockoutJS: Tracking menu clicksKnockoutJS: Event object上构建。 我已经重新考虑了代码以分离viewModel和UI逻辑。我现在要做的是将每个“Menu”对象的“Children”对象数组转换为observableArray,这样我就可以添加/删除菜单的子项来更改我的UI。

这是我的简化代码:

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 not defined”

我的猜测是data.Children = ko.observableArray(data.Children);行未将我的数组正确转换为observableArray。

任何想法都将不胜感激。

1 个答案:

答案 0 :(得分:3)

可以使用您正在使用的语法从数组创建observableArray。它不应该导致问题。我会尝试从您的AJAX请求中回调数据和响应。以确保它们符合您的预期。如果您使用Firefox与Firebug或Chrome可能会有所帮助,那么会调用一些console.log。否则,即使回调中的一些警报(ko.toJSON(数据))也希望显示一些东西。如果说没有定义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]);
    }
  }
});