Reputation: 14581
Or perhaps a better question is, should a directive contain a controller?
For reasons of separation, my index.html is a simple file. Everything is rendered into it via templates. So my index.html is real simple:
<body ng-app="myapp"><mainmenu></mainmenu><div ng-view></div></body>
I don't really need a directive for mainmenu
, but it allows me to put the menu in a separate template file. The main menu itself contains user info, login/logout, and a search box.
<div class="leftmenu" ng-show="isLogin()">
<ul class="menu">
<li><a href="/part1">Part1</a></li>
<li><a href="/part2">Part2</a></li>
<li><a href="/part3">Part3</a></li>
</ul>
<div ng-controller="Search" class="Search><input type="text" ui-select2="s2opts" style="width:250px;" ng-model="search" data-placeholder="search"></input></div>
</div>
<div class="rightmenu">
<ul ng-show="isLogin()" class="menu">
<li><a href="/account">My Account</a></li>
<li><a href="/logout" ng-click="logout()">Logout</a></li>
</ul>
<ul ng-show="!isLogin()" class="menu">
<li><a href="/login">Login</a></li>
<li><a href="/register">Register</a></li>
</ul>
</div>
So there is the menu part, with its own controller, and the search, with its own, embedded between the two parts.
Of course, my mainmenu
directive unit tests fail because SearchController
isn't defined. But this leaves me wondering if I am going about this wrong. Should I even have it like this, a section of html with an explicit ng-controller
defined inside it? Doesn't this create all sorts of weird dependencies?
How should I better structure this? A search
directive that is included so I can unit test it separately? Something feels wrong here structurally...
UPDATE:
As requested, a basic fiddle: http://jsfiddle.net/nj4n44zx/1/
Upvotes: 0
Views: 379
Reputation: 2178
As specified by the Angular documentation, the best practice is to define a controller inside a directive only to expose an API to another directive. Otherwise the link function is sufficient.
See at the bottom of :
By experience using controllers inside a directives shadow what you are doing in your scope. It does not help to have a easy readable code.
I do prefer using the main controller where the directive is included. With a non isolated scope you have access to everything from the link function.
Upvotes: 1
Reputation: 1624
sure your directive can contain a controller because you declare a directive like this
myApp.directive('mainMenu', function() {
return {
restrict: 'E',
replace: true,
scope: true,
templateUrl: 'menu.html',
controller:['$scope', function($scope) {
//define your controller here
}]
};
});
Upvotes: 0
Reputation: 3586
I usually deal with it like that:
app.directive('topMenu', function() {
return {
restrict: 'E', // or whatever You need
templateUrl: '/partials/topmenu', //url to Your template file
controller: function($scope) {
$scope.foo = "bar";
}
};
});
Then, in that template You don't have to add ng-controller.
Upvotes: 0