Reputation: 1925
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
Upvotes: 3
Views: 735
Reputation: 5443
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:
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
template
property or bytemplateUrl
property 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
end
of your root html node, not directly into the previous element you appended
Upvotes: 1
Reputation: 5577
You aren't allowed to add a <div>
element as child from the <ul>
.
Remove the <div id="menu-button">Menu</div>
Upvotes: 0