4

I have started using the Clarity Design Angular project and have run into an issue with the Tree View recursive template that was provided in the 0.10.0-alpha.

https://plnkr.co/edit/KK8rVH1xUGCO7VetgomA?p=preview

    selectableRoot = {
    "@name": "A1",
    "selected": false,
    "expanded": true,
    "children": [
        {
            "@name": "B1",
            "selected": false,
            "children": [
                { "@name": "C1" },
                { "@name": "C2" },
                { "@name": "C3" }
            ]
        },
        {
            "@name": "B2",
            "selected": true,
            "expanded": true,
            "children": [
                { "@name": "D1" },
                {
                    "@name": "D2",
                    "selected": false
                },
                { "@name": "D3" }
            ]
        },
        {
            "@name": "B3",
            "selected": true,
            "children": [
                { "@name": "E1" },
                { "@name": "E2" },
                { 
                  "@name": "E3",
                  "children":
                     { "@name": "F1" }
                }
            ]
        }
    ]
};

When the recursive check hits a match that does not contain an array (but just an object - see A1 > B3 > E3 > F1), it fails to render that item and causes a bug where any collapsible section duplicates child items upon clicking the caret.

Not sure how to fix this if an API that sends the JSON does not put children in an array if there is only one instance. The recursion should account for instances where only one child exists (and is not within an array).

bangelakos
  • 81
  • 6

3 Answers3

4

I was able to solve it from Raja Modamed's input and the addition of one more check on the recursive bit to prevent it from accessing the children without an array (which prevents the ngFor error and returns the functionality to the toggles).

https://plnkr.co/edit/OAujF19FPDqaEWvFfgN1?p=preview

@Component({
selector: "recursive-selectable-structure",
template: `
    <clr-tree-node [(clrSelected)]="item.selected">
        {{item.name}}
        <span *ngIf="item.children?.length > 0">
          <ng-template 
            [clrIfExpanded]="item.expanded" 
            *ngFor="let child of item.children">
              <recursive-selectable-structure
                  [item]="child">
              </recursive-selectable-structure>
          </ng-template>
        </span>
        <ng-template *ngIf="item && item.children && !item.children[0]" [clrIfExpanded]="item.children.expanded">
          <recursive-selectable-structure [item]="item.children">
          </recursive-selectable-structure>
        </ng-template>
    </clr-tree-node>
`

})

bangelakos
  • 81
  • 6
  • You should use `ngProjectAs` and `ng-container` to make sure that the Tree renders correctly as shown here: https://plnkr.co/edit/cUCWhQxaEQxnEIGuxF1c?p=preview – takeradi Aug 15 '17 at 23:15
  • Thanks for the alternative @takeradi. This is preventing the spacing issues I was having. I'll look more into those directives! – bangelakos Aug 16 '17 at 03:22
1

Add one more conditional recursion for the object case in https://plnkr.co/edit/KK8rVH1xUGCO7VetgomA?p=preview replace this code in "recursive-selectable-structure" component

@Component({
selector: "recursive-selectable-structure",
template: `
    <clr-tree-node [(clrSelected)]="item.selected">
        {{item.name}}
        <recursive-selectable-structure *ngIf="item && item.children && !item.children[0]" [item]="item.children">

        </recursive-selectable-structure>
        <ng-template 
          [clrIfExpanded]="item.expanded" 
          *ngFor="let child of item.children">
            <recursive-selectable-structure
                [item]="child">
            </recursive-selectable-structure>
        </ng-template>
    </clr-tree-node>
`

})

Replace and Try this case in same plunker

Raja Mohamed
  • 1,026
  • 9
  • 22
  • This does solve the issue of the last item not rendering, but the issue with clicking on one of the carets to expand/collapse and the items duplicating remains. – bangelakos Aug 13 '17 at 17:29
0

There is a clarity solution now. You can use clarity recursive tree

https://clarity.design/documentation/tree-view#recursive-tree

<clr-tree>
  <clr-tree-node *clrRecursiveFor="let item of items; getChildren: getItemChildren"
                                 [(clrSelected)]="item.selected">
        {{item.name}}
  </clr-tree-node>
</clr-tree>

You also need to define a function in a component which will get children

getItemChildren = (item) => item.children;
Артур Гудиев
  • 1,004
  • 2
  • 10
  • 26