我在这里有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/

10-09 04:59