I am creating a dynamic menu using angular JS. My directive is like
restrict : 'EA',
replace : true,
scope :{menu : "=menu"},
compile: function(element, attributes) {
var linkFunction = function($scope, element, attributes){
element.empty();
element.append('<div id="cssmenu"><ul><div id="menu-button">Menu</div>');
for (i = 0;i<$scope.menu.length;i++){
element.append("<li class='has-sub'><a href='#'> <span>"+$scope.menu[i].name+"</span></a></li>");
}
element.append('</ul></div>');
}
return linkFunction;
}
My HTML code is like
<div ng-app="mainApp" ng-controller="MenuController">
<my-menu menu="menu"></my-menu>
</div>
I am expecting an the resource to be generated like
<div id="cssmenu">
<ul>
<div id="menu-button">Menu</div>
<li class='has-sub'><a href='#'><span>Home</span></a></li>
<li class='has-sub'><a href='#'><span>About</span></a></li>
</ul>
</div>
But the current one generated is like
<my-menu menu="menu" class="ng-isolate-scope">
<div id="cssmenu">
<ul>
<div id="menu-button">Menu</div>
</ul>
</div>
<li class="has-sub"><a href="#"><span>Home</span></a></li>
<li class="has-sub"><a href="#"><span>Contact</span></a></li>
</my-menu>
Issues I am facing
1) Why is the my-menu tag getting displayed ?
2) Why is the and tags getting closed before the tags are printed?
Also Please find the link to Plunker
You are appending things incorrectly to your element. You append elements to elements with jQuery, and jQuery lite, which is what is included with angularjs. You were using it like a string builder. Here is the modifications which work as desired (code modified from your plnkr):
var linkFunction = function($scope, e, attributes){
var element = angular.element('<ul />');;
for (i = 0;i<$scope.menu.length;i++){
var li = angular.element('<li><a href="#">'+$scope.menu[i].name+'</a></li>');
if($scope.menu[i].subList.length > 0 ){
var subList = angular.element('<ul />')
for(j=0;j<$scope.menu[i].subList.length;j++){
var subLi = angular.element('<li><a href="#">'+$scope.menu[i].subList[j].name+'</a></li>');
subList.append(subLi);
}
li.append(subList);
}
element.append(li);
}
e.replaceWith(element);
}
This produces the following markup:
<div ng-app="MenuDirective" ng-controller="MenuController" class="ng-scope">
<ul>
<li>
<a href="#">Home</a>
<ul>
<li>
<a href="#">Home1</a>
</li>
<li>
<a href="#">Home2</a>
</li>
</ul>
</li>
<li>
<a href="#">Contact</a>
<ul>
<li>
<a href="#">Contact1</a>
</li>
<li>
<a href="#">Contact2</a>
</li>
</ul>
</li>
</ul>
</div>
Which is valid html markup. (your desired output is not due to the div as a child of the ul)
and renders like so:
Plnkr
So as answers to your 2 questions:
1) Why is the my-menu tag getting displayed ?
empty() removes the CONTENTS of your element, it doesn't make your element into nothing. Also, your element isn't replaced because there is no template supplied either by
templateproperty or bytemplateUrlproperty and thus there is nothing to replace your tag with.
2) Why is the and tags getting closed before the tags are printed?
Your tags are getting inserted in the wrong places because you're adding strange html nodes to the
endof your root html node, not directly into the previous element you appended
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With