I have directive that brings up the sidebar in my application. I tried to write some code to toggle some content inside this sidebar. But when I trigger the toggle function nothing happens.
This is my directive:
menuItem.directive("menuItem", function() {
return {
restrict: "E",
template: "<div ng-click='toggle()' ng-transclude></div>",
transclude: true,
scope: {
hash: "@"
},
link: function($scope) {
$scope.toggle = function(e) {
$scope.test = !$scope.test;
console.log($scope.test);
$scope.$apply(); // This here brings up error $rootScope: inprog
}
}
}
});
And here is my html:
<menu visible="leftVisible" alignment="left">
<menu-item hash="first-page">
<div>
Testing
</div>
<ul ng-show="test">
<li>1</li>
<li>2</li>
</ul>
</menu-item>
</menu>
How should I resolve this problem, to make the ul toggleable?
The reason is that your directive and your template have different scopes. When you change test
field inside toggle
method, you change it in directive scope, whereas ng-show
directive uses variable from controller scope. And your directive should not depend on controller's markup (and controller-specific variables, like test
). You can create a variable binding in your directive so that it will be responsible for changing visibility and controller markup will be responsible for using this variable to show or hide your menu items. Here is a markup for your controller
<menu visible="leftVisible" alignment="left">
<menu-item hash="first-page" show="someVar">
<div>
Testing
</div>
<ul ng-show="someVar">
<li>1</li>
<li>2</li>
</ul>
</menu-item>
</menu>
And here is a code for your directive
menuItem.directive("menuItem", function () {
return {
restrict: "E",
template: "<div ng-click='toggle()' ng-transclude></div>",
transclude: true,
scope: {
hash: "@",
show: '='
},
link: function ($scope) {
$scope.toggle = function (e) {
$scope.show = !$scope.show;
}
}
}
});
In this case your directive doesn't depend on myVar
variable. It controls visibility using show
attribute. I've also removed $apply
call since your handler called using ng-click
directive which means that angular
is aware of possible changes and you don't have to explicitly start digest cycle.