此问题在KnockoutJS: Tracking menu clicks和KnockoutJS: 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。
任何想法都将不胜感激。
答案 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]);
}
}
});