Separate Controller From Directive?
Solution 1:
If the showLoginDialog
is a common function across components which don't exist in the same hierarchy, then I find it to be less of a headache if you simply implement a service:
app.factory('login', function() {
return {
showLoginDialog: function() {
// whatever
}
};
});
In the example you've provided, there won't be any scope inheritance, so you won't be able to access that method from topNav
. However, if you place common methods and properties in services/factories, you've now given yourself a mechanism by which you can share a single source of truth for information across your application. This is the more "Angular-ish" way to do it.
Edit
To use the service in your controller, just inject it:
app.controller('topNav', function(login) {
$scope.showLogin = login.showLoginDialog;
});
app.controller('registerCtrl', function(login) {
$scope.showLogin = login.showLoginDialog;
});
Depends on the structure of your app, but while the mechanism may change, the policy will be the same.
Solution 2:
Using ng-controller to extend your scope is bad practice.
http://teropa.info/blog/2014/10/24/how-ive-improved-my-angular-apps-by-banning-ng-controller.html
What if you move your directive? You would need to keep applying ng-controllers in different parts of the view and that would get confusing fast.
There are two ways that directives and controllers can talk to each other. One of them Josh Beam already answered which is to use services. The other is to use $broadcast and $emit/$on.
Angular Custom Events using $broadcast, $emit, $on.
For the example you provided, I would have a function on the parent controllers scope that would trigger the directive's showLoginDialog function.
$rootScope.$broadcast('showLogin', data)
Then in your directive's controller do
$rootScope.$on('showLogin', function(e, args){
// do stuff
});
You must also unregister $rootScope listeners to avoid memory leaks. The way you do that is by calling the function that the $on returns and apply it during the scope's $destroy event.
var cleanfunction = $rootScope.$on('showLogin', showLoginDialog());
$scope.$on('$destroy', function(){
cleanfunction();
})
Solution 3:
I can't say that is a bad practice, but it doesn't make sense. If you need a method from a directive accessible outside of it, then the method does not belong in there.
That method should above, perhaps inside of a parent controller / component.
Post a Comment for "Separate Controller From Directive?"