0

I'm trying to create a recursive template in AngularJS. I've read quite some blog posts and SO posts about it, but cannot get my code to work.

I'm trying to make a recursive template to render simple nested expressions with variables and operators. In this case, the nodes in the data tree can be one of multiple types and each type is rendered differently. I try to address this with one Angular template, ng-switch and ng-include.

The template:

<script type="text/ng-template" id="expression.tpl">
    <ng-switch on="expression.type">
        <span ng-switch-when="two-sided-operator">
            <ng-include src="'expression.tpl'" ng-init="expression = expression.left"></ng-include>
            {{ expression.operator }}
            <ng-include src="'expression.tpl'" ng-init="expression = expression.right"></ng-include>
        </span>
        <span ng-switch-when="variable"> {{ expression.name }} </span>
        <span ng-switch-when="literal"> &quot;{{ expression.value }}&quot;</span>
    </ng-switch>
</script>

<ng-include src="'expression.tpl'" onload="expression=testExpression"></ng-include>

The data:

$scope.testExpression = {
    type: "two-sided-operator",
    left: {
        type: "variable",
        name: "foo"
    },
    operator: "==",
    right: {
        type: "literal",
        value: "bar"
    }
};

This however does not render anything. If I remove the internal ng-includes, it does render at least expression.operator.

Can anyone tell me what I am doing wrong? Could there be an issue with the assignment to expression in the ng-init statement?

Thanks for reading this far!

DuXati
  • 335
  • 2
  • 10
  • This [post](http://stackoverflow.com/questions/11412410/angularjs-losing-scope-when-using-ng-include) may help. – Rob J May 05 '16 at 20:13
  • Thanks Rob. I'd already seen that post, but didn't get an answer from it. The fact that `ng-include` creates a new scope is exactly what I want, no? This way, `ng-init="expression = expression.right"` does not overwrite the original `expression`, right? – DuXati May 05 '16 at 20:21
  • There does seem to be something fishy with the scopes. The code gives at least some output when using `onload="expression = $parent.expression.left"`, but now both `ng-include`s in the first `switch` give the same result (twice "bar"). So it seems that `onload` is executed once for the two `ng-include`s. – DuXati May 09 '16 at 05:53

1 Answers1

0

Finally got this to work by using a hack of ng-repeat. The working template:

<script type="text/ng-template" id="expression.tpl">
    <ng-switch on="expression.type">
        <span ng-switch-when="two-sided-operator">
            <span ng-repeat="expression in [expression.left]" ng-include="'expression.tpl'"></span>
            {{ expression.operator }}
            <span ng-repeat="expression in [expression.right]" ng-include="'expression.tpl'"></span>
        </span>
        <span ng-switch-when="variable"> {{ expression.name }} </span>
        <span ng-switch-when="literal"> &quot;{{ expression.value }}&quot;</span>
    </ng-switch>
</script>

I don't understand ng-include deep enough to explain why it did not work though :)

DuXati
  • 335
  • 2
  • 10