Reputation: 36256
Given the following example, I'm curious why scope:true
works as expected to toggle the elements. However, if scope:{}
is used, the toggle method is not called by ng-click
. Through my own experimentation it doesn't make a difference if you use bindToController and controllerAs or not, the problem is the same.
(function(angular) {
'use strict';
angular.module('test', [])
.directive('collapsibleMenu', [function() {
return {
scope: {}, // doesn't work
//scope: true, // works
restrict: 'A',
controller: function() {
var ctrl = this;
ctrl.open = false;
ctrl.toggle = function() {
ctrl.open = !ctrl.open;
console.log('toggle', ctrl.open);
}
},
bindToController: true,
controllerAs: 'ctrl'
};
}]);
})(window.angular);
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.5.0-beta.1/angular.min.js"></script>
<div ng-app="test">
<div collapsible-menu>
<button ng-click="ctrl.toggle()">toggle menu 0</button>
<ul role="menu" ng-show="ctrl.open" class="ng-cloak">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</div>
<div collapsible-menu>
<button ng-click="ctrl.toggle()">toggle menu 1</button>
<ul role="menu" ng-show="ctrl.open" class="ng-cloak">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</div>
</div>
Upvotes: 2
Views: 507
Reputation: 3934
you can use by this way
HTML:
<div ng-app="test">
<div collapsible-menu>
<button ng-click="toggle()">toggle menu 0</button>
<ul role="menu" ng-show="open" class="ng-cloak">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</div>
<div collapsible-menu>
<button ng-click="toggle()">toggle menu 1</button>
<ul role="menu" ng-show="open" class="ng-cloak">
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
</div>
</div>
JS:
angular.module("test", []).
directive("collapsibleMenu", function () {
return {
restrict: "A",
transclude: true,
scope: {},
link: function (scope, element, attrs, ctrl, transclude) {
transclude(scope, function (clone) {
element.append(clone);
});
scope.open = false;
scope.toggle = function () {
scope.open = !scope.open;
console.log('toggle', scope.open);
};
}
};
});
Upvotes: 0
Reputation: 26858
It's called isolat(ed) for a reason. The ctrl
in the isolated scope is not the same as the ctrl
in <button ng-click="ctrl.toggle()">
.
I guess the misunderstanding stems from the fact that you think the content of <div collapsible-menu>
is the content of the directive, but it's not. collapsible-menu
is completely "isolated" (sic!) from the rest of the page.
Upvotes: 3
Reputation: 41162
I am not a master of directives and scope inheritance, but something that strikes me is that your directive isn't really one: it doesn't have a link function, and the code included in the tag should really be in a template. The repetition of the code inside the directive tag is a proof the directive is quite useless: you could as well declare directly the controller in the HTML itself.
Upvotes: 0