1

クライアントが指定したjsonデータを使用して、ネストされたメニューを作成しようとしています。

データ :

var serverData = [
      {
        Id: "menuColorSearch",
        Text: "Color search"
      },
      {
        Id: "menuAncillaryProductMix",
        Text: "Ancillary product mix"
      },
      {
        Id: "menuDocuments",
        Text: "Documents"
      },
      {
        Id: "menuColorInfo",
        ParentId: "menuDocuments",
        Text: "Color info"
      },
      {
        Id: "menuReports",
        ParentId: "menuDocuments",
        Text: "Reports"
      },
      {
        Id: "menuMaintenance",
        Text: "Maintenance"
      },
      {
        Id: "menuPriceManagement",
        ParentId: "menuMaintenance",
        Text: "Price management"
      }
    ];

私はこのようにしようとしています:

var Menu = function(dept, all) {
    var self = this;
    this.id = dept.Id;
    this.name = ko.observable(dept.Text);
    this.parentId = dept.ParentId;
    this.children = ko.observableArray();

    ko.utils.arrayForEach(all || [], function(menu) {

        if(menu.ParentId){
            if (menu.ParentId === self.id) {
                self.children.push(new Menu(menu, all));
            }
        }else{
            new Menu(menu, all)
        }
    });
};

var ViewModel = function(data) {
    this.root = new Menu(data[0], data);
};


$(function() {
    ko.applyBindings(new ViewModel(serverData));
});

テンプレート:

<div data-bind="with: root">
    <ul data-bind="template: 'deptTmpl'">
    </ul>
</div>

<script id="deptTmpl" type="text/html">
    <li>
        <a data-bind="text: name"></a>
        <ul data-bind="template: { name: 'deptTmpl', foreach: children }">
        </ul>
    </li>
</script>

問題は、2 番目と 3 番目のオブジェクトに親 ID がある場合にのみ機能することです。指定されたjsonデータに従ってネストされたメニューを作成するようなものを試しています。そのため、ルートに追加する必要があるオブジェクトに親 ID がありません。オブジェクトに親 ID がある場合は、親 ID に従って追加する必要があります。

KnockoutJS でこれを行う別の方法がある場合は、コードを修正するか、ガイドしてください。

ありがとう

4

1 に答える 1

0

これは、 http://jsfiddle.net/MCNK8/3/に役立つはずです。主なアイデアは、子を親の中に配置して、メインデータ配列を再構築することです

HTML

<script id="nodeTempl" type="text/html">
    <li>
        <a data-bind="text: Text"></a>
        <ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>
    </li>
</script>

<script id="nodeLeafTempl" type="text/html">
    <li>
        <a data-bind="text: Text"></a>
    </li>
</script>

<ul data-bind="template: {name: nodeTemplate, foreach: children }"></ul>

Javascript (@see フィドル)

var serverData = [
      {
        Id: "menuColorSearch",
        Text: "Color search"
      },
      {
        Id: "menuAncillaryProductMix",
          ParentId: 'menuColorSearch',
        Text: "Ancillary product mix"
      },
      {
        Id: "menuDocuments",
        Text: "Documents"
      },
      {
        Id: "menuColorInfo",
        ParentId: "menuReports",
        Text: "Color info"
      },
      {
        Id: "menuReports",
        ParentId: "menuDocuments",
        Text: "Reports"
      },
      {
        Id: "menuMaintenance",
          ParentId: 'menuReports',
        Text: "Maintenance"
      },
      {
        Id: "menuPriceManagement",
        ParentId: "menuMaintenance",
        Text: "Price management"
      }
    ];



function getNestedMenu(index, all) {
    var root = all[index];

    if(!root){
        return all;
    }

    if(!all[index].children){
        all[index].children = [];
    }

    for(var i = 0; i < all.length; i++){
        //<infinity nesting?>

        //put children inside it's parent
        if(all[index].Id == all[i].ParentId){
            all[index].children.push(all[i]);
            all[i].used = true;
        }

        //this is needed for each item, to determine which template to use        
        all[index].nodeTemplate = function(node) {
            return node.children.length > 0 ? 'nodeTempl' : 'nodeLeafTempl';
        }
        //</infinity nesting?>
    }

    return getNestedMenu(++index, all);
};

function getModel(data) {
    var items = getNestedMenu(0, data);

    //<remove duplicates, for infinity nesting only>   
    for(var i = 0; i < items.length; i++){
        if(items[i].used){
            items.splice(i, 1);
            i--;
        }
    }
    //</remove duplicates, for infinity nesting only>
    //<build root item>
    var model = {};
    model.children     = ko.observableArray(items);
    model.nodeTemplate = function(node) {
        return node.children.length > 0 ? 'nodeTempl' : 'nodeLeafTempl';
    }
    //</build root item>
    console.log(items);
    return model;
};


(function() {
    //new ViewModel(serverData);
    ko.applyBindings(getModel(serverData));
})();
于 2013-10-31T04:46:27.467 に答える