我在这里有HTML,当用户单击列表时,我希望它执行功能loadLayerSource
。
<div data-bind="foreach: layerSources">
<label data-bind="text: $data.SubCategory"></label>
<ul data-bind="foreach: $data.CategorySources">
<li data-bind="click: function () {loadLayerSource(Source, Type, URL)}">
<span data-bind="text: ReadableName">Name</span>
<span data-bind="text: Description">Description</span>
</tr>
</ul>
</div>
为了实现这一点,我有以下几点:
//This is data that would be returned from a web service
var jsonData = [{
"SubCategory": "Report",
"CategorySources": [{
"Source": "cvr01",
"Category_ID": "cvr01",
"ReadableName": "Climate Viewer Reports",
"Type": "kml",
"URL": "/layers/kml/cv-reports/cv-reports-0415.kml",
"Description": "Content disclaimer etc"
}]
}, {
"SubCategory": "Earthquake",
"CategorySources": [{
"Source": "usgs-all-hour",
"Category_ID": "",
"ReadableName": "USGS - All Earthquakes (Last Hour)",
"Type": "geojson",
"URL": "http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.geojson",
"Description": "Content disclaimer etc"
}, {
"Source": "kml-emsc",
"Category_ID": "",
"ReadableName": "Euro-Med Earthquakes - CSEM/EMSC",
"Type": "kml",
"URL": "http://www.emsc-csem.org/Earthquake/Map/earth/kml.php",
"Description": "Content disclaimer etc"
}]
}];
//This is our ProductType model
var typeModel = function (source, name, type, url, description) {
var self = this;
self.Source = ko.observable(source);
self.ReadableName = ko.observable(name);
self.Type = ko.observable(type);
self.URL = ko.observable(url);
self.Description = ko.observable(description);
};
var typeReturn = function (source, name, type, url, description) {
alert(source + name);
};
//This is the model that contains the header (Category) and an array of typeModels (Products)
var gridModel = function (subcategory, categorySources) {
var self = this;
self.SubCategory = subcategory;
self.CategorySources = ko.observableArray(categorySources);
};
//This is the viewmodel that contains an array of gridModels
var settingsViewModel = function () {
this.layerSources = ko.observableArray();
var me = this;
//This is where you would normally make an ajax call to get your data
//TODO figure out a way to reduce the amount of loops
$.each(jsonData, function (key, value) {
$.each(value, function (k, v) {
if (k == 'CategorySources') {
var categorySources = [];
$.each(v, function (a, b) {
categorySources.push(new typeModel(b.Source, b.ReadableName, b.Type, b.URL, b.Description));
});
me.layerSources.push(new gridModel(value.SubCategory, categorySources));
}
});
});
};
ko.applyBindings(new settingsViewModel());
无论我将以下代码放在哪里,都会出现未定义的错误。
self.loadLayerSource = function() {
alert(layerType);
};
jsFiddle Link
最佳答案
请参阅更新的小提琴:http://jsfiddle.net/ucz8yzxy/2/
您需要用loadLayerSource
适当地限制对$root
的调用,因为您在foreach
循环中有2个层次。另外,如果在视图模型中,loadLayerSource
应该附加到this
而不是self
,因为其中没有定义self
。
并且由于这些字段是可观察的,因此请确保您对它们进行了评估(原谅)。
关于javascript - knockout -foreach循环中具有多个模型的功能,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/32143843/