Knockout - 具有多个模型的foreach循环中的函数

时间:2015-08-21 15:12:03

标签: javascript knockout.js foreach model

我在这里有HTML,当用户点击列表时,我希望它执行一个函数Files

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());

jsFiddle Link

1 个答案:

答案 0 :(得分:1)

请参阅更新的小提琴:the interface in MassTransit isn't generic

您需要使用loadLayerSource将调用范围正确地调整为$root,因为您在foreach循环中的深度为2级。此外,loadLayerSource,如果在viewModel中,则应附加到this而不是self,因为self未在其中定义。

由于这些字段是可观察的,因此请确保对它们进行评估(parens)。