将Knockout数据驱动表添加到Knockout Data Driven Accordion Pane

时间:2012-12-20 12:39:21

标签: jquery json knockout.js

我正在尝试创建一种我希望在我的应用程序中使用的通用控件。它将是一个标准的手风琴(我使用Twitter Bootstrap),这取决于我从服务器收到的JSON数据将创建多少个手风琴章节。在每个手风琴部分,我想添加一个普通的HTML表格,该表格也是使用从服务器获取的JSON数据构建的。 一切都将在客户端运行,接受Ajax的初始帖子以获取JSON信息。所以我相信某种HTML模板是必需的吗?

所以这就是我到目前为止所拥有的。 JSON DATA:

 var data = {
        "d": [
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.AvailibleStock",
        "WarehouseID": 1,
        "ProductSKUID": 1,
        "ProductSKUName": "Decoder 1132",
        "WarehouseName": "SoftwareDevelopmentTest",
        "Status": "Staging",
        "QtyUnassigned": 10
    },
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.AvailibleStock",
        "WarehouseID": 1,
        "ProductSKUID": 2,
        "ProductSKUName": "Decoder 1131",
        "WarehouseName": "SoftwareDevelopmentTest",
        "Status": "Staging",
        "QtyUnassigned": 5
    }
]
    };

    var data2 = {
        "d": [
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
        "WarehouseID": 1,
        "ProductSKUID": 2,
        "LotID": 2,
        "LotName": "TestLot2",
        "AreaID": 8,
        "AreaName": "TestArea3L2",
        "BinID": 18,
        "BinName": "Area8Bin2"
    },
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
        "WarehouseID": 1,
        "ProductSKUID": 2,
        "LotID": 3,
        "LotName": "TestLot3",
        "AreaID": 11,
        "AreaName": "TestArea2L3",
        "BinID": 20,
        "BinName": "Area10Bin1"
    },
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
        "WarehouseID": 1,
        "ProductSKUID": 2,
        "LotID": 4,
        "LotName": "TestLot4",
        "AreaID": 15,
        "AreaName": "TestArea2L4",
        "BinID": 24,
        "BinName": "Area14Bin1"
    },
     {
         "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
         "WarehouseID": 1,
         "ProductSKUID": 1,
         "LotID": 2,
         "LotName": "TestLot2",
         "AreaID": 8,
         "AreaName": "TestArea3L2",
         "BinID": 18,
         "BinName": "Area8Bin2"
     },
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
        "WarehouseID": 1,
        "ProductSKUID": 1,
        "LotID": 3,
        "LotName": "TestLot3",
        "AreaID": 11,
        "AreaName": "TestArea2L3",
        "BinID": 20,
        "BinName": "Area10Bin1"
    },
    {
        "__type": "Warehouse.Tracntrace.Members_Only.DLL.StockMovement.StockReturnMethod",
        "WarehouseID": 1,
        "ProductSKUID": 1,
        "LotID": 4,
        "LotName": "TestLot4",
        "AreaID": 15,
        "AreaName": "TestArea2L4",
        "BinID": 24,
        "BinName": "Area14Bin1"
    }
]
    };

我刚刚使用了2个AJAX调用来从我的服务器获取此信息,正如您所看到的,2个数据集之间存在相似性(两者都可以通过ProductSKUID和WarehouseID与彼此相关)。

接下来,我使用我的KnockoutJS和Standard JQuery来构建手风琴的功能,方法是使用innerHTML方法创建手风琴并在手风琴中创建HTML表。

 var ProductViewmodel;
    //debugger; 

    //Binds ViewModel
    function bindProductModel(Products) {
        var self = this;
        self.items = ko.mapping.fromJS([]);
        ProductViewmodel = ko.mapping.fromJS(Products.d, self.items);
        console.log(ProductViewmodel());

    }

    //Binds First DataSet
    function bindModel(vm, data) {
        var self = this;
        vm.Locations = ko.mapping.fromJS(data.d);
        console.log(ProductViewmodel());
    }

    //Create Table In Accordion PANE based on Data
    //This Creates The Table in Each Accordion Pane
    function InjectBody() {
        var bodyContainer = document.getElementById('injectbody');
        var body = bodyContainer.innerHTML;
        body = body + '<table class="table table-striped"><thead><tr><th>#</th><th>Lot</th><th>Area</th><th>Bin</th><th>Qty To Assign</th></tr></thead><tbody data-bind="foreach: Locations"><tr><td id="Assign"><input type="checkbox" /></td><td id="Lot" data-bind="text: LotName"></td><td id="Area" data-bind="text: AreaName"></td><td id="Bin" data-bind="text: BinName"></td><td id="QtyToAssign"><input type="text" /></td></tr></tbody></table>';
        bodyContainer.innerHTML = body;
    }

    //Create Accordian Panes
    //This Creates The Hyperlink Based On JSON DATA
    function BuildLinkFromJSON() {
        var link;
        link = '<a data-bind="foreach: items" class="accordion-toggle" data-toggle="collapse" data-parent="#accordion" href="#collapse"><span data-bind="text: ProductSKUName"></span></a>';
        //This Creates The Table in Each Accordion Pane
        InjectBody();
        return link;
    }

    //Create Accordian Header
    //This Creates Each Header in the Accordian
    function BuildAccordian() {
        //This Creates The Hyperlink Based On JSON DATA
        var link = BuildLinkFromJSON();
        var eventsContainer = document.getElementById('accordion');
        var events = eventsContainer.innerHTML;
        events = events + '<div class="accordion-group"><div class="accordion-heading">' + link + '</div><div id="collapseOne" class="accordion-body collapse in"><div class="accordion-inner"><div id="injectbody"></div></div></div>';
        eventsContainer.innerHTML = events;
    }


    //Starting Function
    //This Creates the ProductViewModel Binding of both DataSets
    $(document).ready(function () {
        bindProductModel(data);
        bindModel(ProductViewmodel()[0], data2);
        ko.applyBindings(ProductViewmodel);

    })

好吧它似乎彻底失败了,我不知道该怎么做才能解决它...我创建了这个Fiddle但是没有给出输出。任何帮助将不胜感激!!

1 个答案:

答案 0 :(得分:0)

当我为KO执行自定义“控件”时,我使用字符串模板源并在脚本中为“控件”编写HTML。您可以查看我正在进行中的工作KO Combobox,了解如何做到这一点

https://github.com/AndersMalmgren/Knockout.Combobox/blob/master/src/knockout.combobox.js

查看模板部分

//string template source engine
var stringTemplateSource = function (template) {
    this.template = template;
};

stringTemplateSource.prototype.text = function () {
    return this.template;
};

var stringTemplateEngine = new ko.nativeTemplateEngine();
stringTemplateEngine.makeTemplateSource = function (template) {
    return new stringTemplateSource(template);
};

var template= '<div data-bind="with: model">\
   <span data-bind="text: data"></span>\
</div>';

并从自定义绑定中应用模板

ko.bindingHandlers.myBinding = {
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
        var model = new MyBindingViewModel(valueAccessor());
        ko.renderTemplate(template, bindingContext.createChildContext(model), { templateEngine: stringTemplateEngine }, element, "replaceChildren");

        return { controlsDescendantBindings: true };
    }
};

现在,您可以使用自定义绑定,例如视图中的常规绑定

<div data-bind="myBinding: model"></div>