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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With