1

I'm trying to create a nested directive with angularjs.

This is my code: (http://jsfiddle.net/TH55L/)

JS:

myApp.directive('nodo', function ($compile) {
    return {
        restrict: 'E',
        terminal: true,
        scope: {
            n: "="
        },
        link: function (scope, element, attrs) {
            var template = "<p>{{n.name}}</p>";

            if (scope.n.nodo != null) {
                template += '<nodo n="n.nodo"></nodo>';
            }

            var newElement = angular.element(template);
            $compile(newElement)(scope);
            element.replaceWith(newElement);
        }
    }
})

function MyCtrl($scope) {
    $scope.nodo = {
        "name": "Level 0",
        "nodo": {
            "name": "Level 1",
            "nodo": {
                "name": "Level 2",
                "nodo": {
                    "name": "Level 3",
                    "nodo": null
                }
            }
        }
    };
}

HTML:

<div ng-controller="MyCtrl">
    <nodo n="nodo"></nodo>
</div>

The expected result is this:

<p>Level 0</p><p>Level 1</p><p>Level 2</p><p>Level 3</p>

But i'm only getting this:

<p>Level 0</p>

It's like the $compile(newElement)(scope) not recognizes the directive.

Here is an example in Knockoutjs of what I wanna do: http://jsfiddle.net/y64rY/

2
  • Do all p elements have to be at the same level? It seems that you're going about this in a very roundabout way. Why are you constantly replacing the elements contents. Commented Dec 5, 2013 at 15:32
  • @MathewBerg p elements must be in the same level. I'm new in angular (coming from kncokout), if you see another way to do this using recursive templates please tell me. Commented Dec 5, 2013 at 15:48

2 Answers 2

1

In order to get them repeating like how you want, you should convert the object you have on the fly to the an array and then use the data-ng-repeat directive:

        scope.nodes = [];

        function recursive(parent){
            scope.nodes.push({
                name: parent.name
            });
            if(parent.nodo){
                recursive(parent.nodo);
            }
        }

        recursive(scope.nodo);

template: '<div><p data-ng-repeat="node in nodes">{{ node.name }}</p></div>',

jsfiddle http://jsfiddle.net/kEyqz/

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

2 Comments

check the link of jsfiddle. Any way, I could do it with your answer! Here is the result: jsfiddle.net/TH55L/7
Perfect, wasn't sure if you needed it in a directive or not.
0

You can accomplish that using two directives:

var myApp = angular.module('myApp',[]);

myApp.directive('tree', function ($compile) {
    return {
        restrict: 'E',
        terminal: true,
        replace: true,
        scope: {
            root: "="
        },
        link: function (scope, element, attrs) {
            var nodoTemplate = '<nodo node="node"></nodo>';

            /* Your first nodo is the root. We put it on scope to use this on $compile */
            scope.node = scope.root
            while (scope.node != null) {
                /* Compile and append the nodo */
                var c = $compile(nodoTemplate)(scope);
                element.append(c);
                /* go to next nodo */
                scope.node = scope.node.nodo;
            }      
        }
    }
});

myApp.directive('nodo', function ($compile) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            node: "="
        },
        template: "<p></p>",
        link: function(scope, element, attrs) {
            element.text(scope.node.name);
        }
    }
})

And in your html:

<tree root="nodo"></tree>

Working Fiddle

3 Comments

This solution work for this example but is useless, in my proyect i have more than a simple p with text inside.
@FacundoPedazzini Then you edit the nodo directive to your needs. How can I possible imagine what you would want? ;)
@FacundoPedazzini what were you thinking?

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.