AngularJS has the super nifty ngTransclude directive, which replaces html in your directive's template with html from the controller's template. If you're using an isolated scope in your directive, you can access variables from the controller's scope using ngTransclude.
I was attempting to do this when I ended up with a seemingly random result. ngTransclude inside of a ngRepeat returned the value from the directive's scope instead of the controller's scope.
Going off of the AngularJS documentation, I created a Plunker: http://plnkr.co/edit/GtrYtGoy2fnvgkwLFAGN?p=preview
JS
angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
$scope.names = ['Tobias', 'Funke'];
}])
.directive('myDialog', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
templateUrl: 'my-dialog.html',
link: function (scope, element) {
scope.names = ['Jeff', 'Bridges'];
}
};
});
index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Example - example-example87-production</title>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
<script src="script.js"></script>
</head>
<body ng-app="docsTransclusionExample">
<div ng-controller="Controller">
<my-dialog>Check out the contents, {{names}}!</my-dialog>
</div>
</body>
</html>
my-dialog.html
<div class="alert" ng-transclude></div>
<div ng-repeat="name in names">
<div class="alert" ng-transclude></div>
{{name}}
</div>
<div class="alert" ng-transclude></div>
This code returns:
Check out the contents, ["Tobias","Funke"]!
Check out the contents, ["Jeff","Bridges"]!
Jeff
Check out the contents, ["Jeff","Bridges"]!
Bridges
Check out the contents, ["Tobias","Funke"]!
According to the documentation I've read, and this transclusion and scopes article I found for transclusion and scope, transclusion should ONLY take in the controller's scope, meaning the middle two "Check out the contents, {{names}}!" should read the same as the outer two.
Further experimentation had me changing the AngularJS version from 1.2.15 to the 1.3.0 rc
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.0-rc.1/angular.min.js"></script>
which results in the correct (as far as I understand it) output:
Check out the contents, ["Tobias","Funke"]!
Check out the contents, ["Tobias","Funke"]!
Jeff
Check out the contents, ["Tobias","Funke"]!
Bridges
Check out the contents, ["Tobias","Funke"]!
Is there a workaround for this problem that I can use with 1.2.15 or am I stuck when using this version? What is the correct behavior supposed to be?
From changelog of 1.3.0b11:
ngRepeat: ensure that the correct (transcluded) scope is used (b87e5fc0)
Same for ng-if (has the same strange different behavior when switching between 1.2.15
and 1.3.0-rc.1
in your plunker).
So the correct one is when using 1.3.0-rc.1
.
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