简体   繁体   中英

Want to create n level menu component

I am using aurelia and ES6 to create an level menu component. The json I am getting is:

data: [
  levelId: 1,
  label: 'Level1',
  chlidItems: [
    {
       levelId: 2,
       label: 'Level2',
       childItems: [] // so on multiple levels
    }
  ]
]

In HTML, I am showing base level directly using repeat.for on data.

<div class="main-level" ref="pgElm">
  <div class="main-label" repeat.for="dataObj of data" click.trigger="openChildItems($event, dataObj, $index)">${dataObj.label}</div>
</div>

I want to add child items on click. I tried two approaches for it.

1st I used aurelia templating engine to add child div.

openChildItems(_event, _dataObj, _index) {
    this.$pgElm = $(this.pgElm);
    if (_dataObj && _dataObj.childItems && _dataObj.childItems.length) {
      let parentDiv = null;
      if (_dataObj.levelId === this.schema.data[0].levelId) {
        parentDiv = this.$pgElm.find('.main-label')[_index];
      } else {
        parentDiv = this.$pgElm.find('.child-' + _dataObj.levelId + '-label')[_index];
      }

      let childDiv = document.createElement('div');
      childDiv.className = 'child-' + _dataObj.childItems[0].levelId;
      parentDiv.appendChild(childDiv);
      this.className = 'child-' + _dataObj.childItems[0].levelId + '-label';
      this.variableName = 'childItems' + _dataObj.childItems[0].levelId ;
      this.viewData['childItems' + _dataObj.childItems[0].levelId] = _dataObj.childItems;
      childDiv.innerHTML = "<div class='${className}' repeat.for='child of viewData[variableName]' click.trigger='openChildItems($event, child, $index)'>${child.label}</div>";
      let view = this.templatingEngine.enhance({element: childDiv, bindingContext: this});
    }
  }

The problem with this approach is that the data is changing through all levels.

Then I tried to use another approach to append the divs.

 openChildItems(_event, _dataObj, _index) {
    this.$pgElm = $(this.pgElm);
    if (_dataObj && _dataObj.childItems && _dataObj.childItems.length) {
      let parentDiv = null;
      if (_dataObj.levelId === this.schema.data[0].levelId) {
        parentDiv = this.$pgElm.find('.main-label')[_index];
      } else {
        parentDiv = this.$pgElm.find('.child-' + _dataObj.levelId + '-label')[_index];
      }

      let childDiv = document.createElement('div');
      childDiv.className = 'child-' + _dataObj.childItems[0].levelId;
      $(parentDiv).append(childDiv);

      let childItems = _dataObj.childItems;
      let index = 0;
      for (let child of childItems) {
        let childLabelDiv = document.createElement('div');
        childLabelDiv.className = 'child-' + child.levelId + '-label';
        childLabelDiv.innerHTML = child.label;
        childLabelDiv.addEventListener('click', (e)=>{
             this.evtOpenChildItems(e, child, index);
             e.stopPropagation();
        });
        $(childDiv).append(childLabelDiv);
        index ++;
      }
    }
  }

Now the problem i am getting with this is I am getting parentDiv as undefined when i am clicking on 1st level child items.

Please help me in where i am going wrong with the approaches and if there is another way to achieve it?

I don't really get why you are dynamically constructing it like that, can't you do something like:

//my-tree-component.ts
<div class="main-level" ref="pgElm">
  <div class="main-label" repeat.for="dataObj of data" 
       click.trigger="toggleOpenClose()">
    ${dataObj.label}
    <my-tree-component if.bind="open"></my-tree-component>
  </div>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM