0

I would like to create a treeview table from this model:

[
{Id: 1,
 Type: Item
},
{Id: 2,
 Type: Group,
 Children[
    {Id: 3,
     Type: Item
    },
    {Id: 4,
     Type: Item
    },
    {Id: 5,
    Type: Group,
    Children[
        {Id: 6,
         Type: Item
        },
        .... //there may be an infinite number of node
        ]
   }]
},
{Id: x,
 Type: Item
}

But I can't figure out how to do that using directives and ng-repeat.

Result may be like this :

----------------------------------------------------
| Item 1                                |
----------------------------------------------------
| Group 2                               |
----------------------------------------------------
|     Item 3                            |
----------------------------------------------------
|     Item 4                            |
----------------------------------------------------
|     Group 5                           |
----------------------------------------------------
|         Item 7                        |
----------------------------------------------------
[...]
----------------------------------------------------
| Item x                                |
----------------------------------------------------

I tried to nest multiple tbody using recursive directive in my table, but it doesn't work.

Any solution ?

5
  • One of solutions is to flatten arrays in recursion and use ng-repeat Commented Apr 22, 2015 at 10:02
  • If you are looking for something simpler, take a look at ng-grid. It does what you are trying to achieve with grouping. In this example i agree with YD1m, you must flatten the array. And be careful with ng-repeat in an hierarchic view, you might get stuck. Commented Apr 22, 2015 at 10:08
  • @YD1m How can i control if my item are displayed or not regarding their parent's expanded property ? Commented Apr 22, 2015 at 10:22
  • @Pierolain add to all nodes Parent property Commented Apr 22, 2015 at 10:31
  • I finally find out a way to display my treeview using your method @YD1M and a loop to find parent. Thanks for help Commented Apr 22, 2015 at 14:39

3 Answers 3

2

Tried to do the same with TABLE - TR with no luck.

  1. Tried to write an attribute- directive (myTreeItem) with replace:true and template like

<tr><td>{{item.Name}}</td></tr>
<tr my-tree-item item="item"></tr>

error: in case of replace:true template must contain ony one root element

  1. Tried to write element-directive like this:
    <tr><td>{{item.Name}}</td></tr>
    <my-tree-item item="item"></my-tree-item>
    
    with using:
       
    <table>
            <tbody>
              <my-tree-item ng-repeat="item in elements" item="item"></my-tree-item>
            </tbody>
    </table>

Browser saw that in tbody there's something not TR and throws it out of a TABLE tag :)

  1. Tried to use "replaceWithChild" - worked with div's and not with TR's
  2. My last hope was directive as comment, but there is no way to pass more than one string parameter

Ended up with dumb solution, with no recursion. For those who have limited tree depth and needs fast solution: plunker example

Sign up to request clarification or add additional context in comments.

Comments

0

You can use the following directive:

myApp.directive('replaceWithChild', function($timeout) {
	return {
		require: 'ngInclude',
		restrict: 'A',
		link: function(scope, el, attrs) {
			$timeout(function() {
				el.replaceWith(el.children());
			});
		}
	};
});

Note: The $timeout is important for waiting all elements are ready.
Here the Plunker for example

Comments

0

Better late than never. I was able to get this to work with using Fabrice's answer as shown below. However I ended up not using it because it performed badly with a large number or rows/columns. So instead I used a flattened list with a normal ng-repeat.

    angular
        .module('app')
        .directive('recursive-row', RecursiveRow);

    RecursiveRow.$inject = ['$timeout'];

    function RecursiveRow($timeout)
    {
        return {
            restrict: 'A',
            templateUrl: 'templates/recursive-row.html',
            scope: {
                model: '=',
            },
            link: function (scope, el, attrs)
            {
                $timeout(function ()
                {
                    el.replaceWith(el.children());
                });
            }
        };
    }
    <script type="text/ng-template" id="templates/recursive-row.html">
        <tr>
            <td>{{model.heading}}</td>
            <td>{{model.detail}}</td>
        </tr>

        <tr recursive-row
            ng-repeat="child in model.children track by child.id"
            model="child"></tr>
    </script>
    <table>
        <thead>
            <tr>
                <th></th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            <tr recursive-row
                ng-repeat="model in hierarchy track by model.id"
                model="model">
            </tr>
        </tbody>
    </table>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.