Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS: Access directive's isolated scope from parent controller

Tags:

angularjs

I want to write a directive with isolated scope but also want to make that scope available for the parent scope's controller. I found this solution:

<div ng-controller="Main">   <popupbutton directive-scope="popup"></popupbutton> </div>  app.directive('popupbutton', [function() {   return {     restrict:   "E",     scope:      {           directiveScope: "="     },     link:       function(sc, el, attrs) {       sc.directiveScope = sc;       sc.testvalue = 'foo';     }   };   }]);  app.controller('Main', function($scope) {   alert($scope.popup.testvalue);  // Where did the property 'popup' come from?!? }); 

See Plunker.

I find this a bit ugly because it involves writing an attribute in HTML and in controller's code you can't tell where a scope property came from. Is there a better way to do this?

Edit:

Besides, it seems that $scope.popup isn't even available when controller 'Main' is run. The directive's linking function isn't executed yet?

like image 275
Esa Toivola Avatar asked Jan 26 '13 18:01

Esa Toivola


1 Answers

To maintain proper separation of concerns, you should not mix scopes. Not to mention that it will be hard to synchronize. To summarize: your directive should not know anything about the parent scope (or its controller) and your controller should not know anything about a directive's internals. They are separate components in separate layers.

The proper way to communicate between a controller and a directive is through directive attributes. In the case of a popup, say, this can be done with a simple boolean value.

The controller and directive:

app.directive('popupbutton', [function() {   return {     restrict: "E",     scope: { isOpen: "=" },     template: '<a ng-click="isOpen = !isOpen">Toggle</a><div>Open? {{isOpen}}'   }; }]);  app.controller('MainCtrl', function($scope) {   $scope.isOpen = false; }); 

And the markup:

<popupbutton is-open="isOpen"></popupbutton> 

This method requires no logic, works out of the box, and maintains clean separation of concerns. Here's an updated plunker: http://plnkr.co/edit/otIaGCLmiNdGcYEgi60f?p=preview

like image 79
Josh David Miller Avatar answered Oct 10 '22 05:10

Josh David Miller