I have the following code. It loops over JSON to produce a nested ul list. I have a click event that executes the function toggleNav() bound to a anchor tag. I don't know why the click event is bound twice to the element. Also I am new to angular, is there a document that explains this concept out there? Thanks!
define([
'/assets/angularapp/AppDirectives.js',
'highstock'
], function (directives) {
directives.directive('collection', function () {
return {
restrict: "E", //declare by element
replace: true,
scope: {
collection: '='
},
template: "<ul class=\"nav nav-list tree\"><member ng-repeat=\"member in collection\" member=\"member\"></member></ul>"
}
})
directives.directive('member', function ($compile) {
return {
restrict: "E",
replace: true,
scope: {
member: '='
},
template: "<li ng-show=\"member.open\"><span><input type=\"checkbox\" ng-model=\"member.selected\" class=\"sideChkbox\"><a class=\"tree-toggle\" ng-click=\"toggleNav()\"><i class=\"icon-chevron-right\"></i>{{member.data}}</a></span></li>",
controller: function($scope, $element){
$scope.toggleNav = function(){
angular.forEach($scope.member.children,function(child,key){
if(child.open==true){
alert("a")
child.open=false;
} else {
child.open=true;
alert("b")
}
})
}
},
link: function (scope, element, attrs) {
if (angular.isArray(scope.member.children)) {
element.append("<collection collection='member.children'></collection>");
$compile(element.contents())(scope)
}
}
}
})
It is because you are compiling the element.contents(), including the <a> with ng-click, which should be already compiled. At the time you call a manual compile, it gets compiled again.
you can fix it by this:
...
if (angular.isArray(scope.member.children)) {
var newMemEL = angular.element("<collection collection='member.children'></collection>");
element.append(newMemEL);
$compile(newMemEL)(scope);
}
...
It looks like you are trying to create a treeview, in this case, it would be better to use ngInclude instead of creating custom directives, have a look at this plunker, note that it will not work with Angular 1.2.0rc1 due to this issue
@Mr.DucNguyen's answer is correct, but if you don't want to further manipulate the DOM, you can approach it another way.
Flag the element as completed during the link function, so when it tries to link again it fails.
link: function (scope, element, attrs) {
// stop an already linked element from continuing
if (element.attr('collection-linked')) {
return;
}
// otherwise, add a completed flag to this element
element.attr('collection-linked', true);
// continue your linking ...
}
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