Sarfraz Ahmad
Sarfraz Ahmad

Reputation: 1439

Recursion using Angularjs and Append Elemnts to an HTML Template

I am quite new to Angularjs . I am working on an app which use Angularjs for front end and django-tastypie for back end. What I am doing is i have a topics list where topics are nested in each others as child parents for multiple levels. these levels can be multiple. my data structure is as

[{'id':1,
   'name':'science',
   'subtopics':[{
                 'id':1,
                  'name':'chemistry',
                   'subtopics':[{'id':1,
                                 'name':'atom',
                                  'subtopics':[{'id':1,'name':'science',:'subtopics':[]]
]]}}

I may have this nested list for multiple levels . What i want to do is that i want to do is that if I select an element from select list which has subtopics, a HTML is appended to the template and selected elements subtopics become its elements . If there is only one level there will be only one select menu on the template. Tell me how can I represent this tree in Template using angular. or tell if anyone have any better idea.

my desired HTML rendering is like

<label>Topic Level 1:</label>
<select ng-model="qt_topic_level_1" ng-options="topic.name for topic in qt_topicslist_level_1" ng-change="showSecondLevelTopics()">
</select></br>
<label ng-show="secondleveltopicslabel" ng-true-value="true" ng-false-value="false">Topic Level 2:</label>
<select ng-model="qt_topic_level_2" ng-options="topic.name for topic in qt_topicslist_level_2" ng-change="getThirdleveltopics()" ng-show="secondleveltopicslist" ng-true-value="true" ng-false-value="false" >
</select></br>

means if the subtopics are available in the selected topics list a select tag should be appended to the template to select the sub topic and so on. First time I want to show the root elements only. and then on click want to show the subtopics level by level.

Upvotes: 2

Views: 447

Answers (1)

package
package

Reputation: 4801

You need to split your template in to two. The first one can by used as recursion container, the "main" topics template:

<div ng-repeat="topic in topics">
  <div include-tpl="path/to/topic/tpl-recursive"></div>
</div>

And the single topic's template:

<div class="topic">
  <!-- ..topic content.. -->

  <div class="subtopics">
     <div ng-repeat="topic in topic.subtopics">
       <div include-tpl="path/to/topic/tpl-recursive"></div>
     </div>
  </div>
</div>

I use custom include-tpl directive because ngInclude creates new scope (or used to create, I'm currently using a bit dated version of angular):

.directive('includeTpl', ['$compile', '$http', function($compile, $http){
  return {
    restrict: 'A',
    link: function($scope, $element, $attrs) {
        var replace = typeof $attrs.replace !== 'undefined';
          $scope.$watch($attrs.includeTpl, function(value) {
            if (!value) return;
            $http.get(value).then(function(html){
              var content = $compile(html)($scope);
              if (replace) $element.replaceWith(content);
              else $element.html(content);
            });
           });
    }
  };
}])

Upvotes: 2

Related Questions