I have a tab control which enables content within the control to be shown or hidden based on the selected tab.
This works well enough, but the content of the tab panes starts behaving oddly with the scope. Referencing the scope within the transcluded content doesn't seem to refer to the defined controller scope any more.
This can be seen with any directive which has transcluded content. Given the specific controller:
app.controller("MainCtrl", function ($scope) {
$scope.getTestText = function () {
alert($scope.testText);
alert(this.testText);
}
});
Which is used in the following markup:
<h1>Outside Tab</h1>
<div>
<input type="text" ng-model="testText" />
<button ng-click="testText = 'outside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
<simple-directive>
<h1>Inside Directive</h1>
<div>
<input type="text" ng-model="testText" />
<button ng-click="testText = 'inside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
</simple-directive>
See this plunker.
If you click the top "Set Test Text" button then the "Get Test Text" button, the two alerts show the same thing ("outside"). If you click the second "Set Test Text" button then "Get Test Text", there is a different result: although "this" has the expected "inside" value, the value on the scope is still "outside".
One workaround is to define the controller inside the transcluded content, like so:
<simple-directive>
<h1>Inside Directive</h1>
<div ng-controller="MainCtrl">
<input type="text" ng-model="testText" />
<button ng-click="testText = 'inside'">Set Test Text</button>
<button ng-click="getTestText()">Get Test Text</button>
{{testText}}
</div>
</simple-directive>
But I'd rather avoid this if possible.
So my question: is there a better way of doing this that doesn't change the scope? Is this just expected behaviour?