Reputation: 1531
I want to be able to do something like this in my app:
<pill-autocomplete>
<pill-template>{{item.name}}</pill-template>
</pill-autocomplete>
Where pill-autocomplete
has a template that transcludes into a child directive like this:
<pills ng-transclude="pillTemplate"></pills>
<input type="text">
It doesn't seem possible given that ng-transclude creates scope and the <pills>
directive has an isolate scope.
One way I have thought of accomplishing this is by injecting the pill template inside the autocomplete's template function. The problem with that is that it loses the transclusion scope. I'd also have to do this in every directive that has similar behavior with pills.
Is there any other way to accomplish this in angular 1.x?
Upvotes: 8
Views: 1025
Reputation: 196
The problem is that by the time you transclude data from pill-autocomplete to pills you already have deleted the content inside pills.
The transclusion replaces the content under the directive template so the content in the pills directive template simply cannot be loaded because has been overridden by the transclusion.
My suggestion is simple, not use directly the tag with the ng-transclude inside, use an internal div to make possible the directive to load its content
angular.module('app', []);
var app = angular.module('app');
'use strict';
var app = angular.module('app');
app.controller('testController', [
function () {
var vm = this;
vm.name = 'Jimmy';
}]);
app.directive('pillAutocomplete', function () {
return {
priority: 100,
restrict: 'E',
transclude: true,
template: '<pills><p>From Pill-Autocomplete</p><div ng-transclude><div></pills>'
};
});
app.directive('pills', function () {
return {
restrict: 'E',
transclude: true,
link: function (scope, element, attrs) {
scope.style = true;
},
template: '<p>Inside Pills</p><div ng-class="{pillscolor : style}" ng-transclude></div>'
};
});
.pillscolor{
color: green;
font-size: 20px;
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<article ng-app="app">
<section ng-controller="testController as test">
Controller scope - {{test.name}}
<pill-autocomplete>
From controller - {{test.name}}
</pill-autocomplete>
</section>
</article>
Upvotes: 2
Reputation: 1
This demo maybe help
https://docs.angularjs.org/guide/directive
<my-tabs>
<my-pane title="Hello">
<p>Lorem ipsum dolor sit amet</p>
</my-pane>
<my-pane title="World">
<em>Mauris elementum elementum enim at suscipit.</em>
<p><a href ng-click="i = i + 1">counter: {{i || 0}}</a></p>
</my-pane>
</my-tabs>
<div class="tabbable">
<ul class="nav nav-tabs">
<li ng-repeat="pane in panes" ng-class="{active:pane.selected}">
<a href="" ng-click="select(pane)">{{pane.title}}</a>
</li>
</ul>
<div class="tab-content" ng-transclude></div>
</div>
<div class="tab-pane" ng-show="selected">
<h4>{{title}}</h4>
<div ng-transclude></div>
</div>
angular.module('docsTabsExample', [])
.directive('myTabs', function() {
return {
restrict: 'E',
transclude: true,
scope: {},
controller: ['$scope', function MyTabsController($scope) {
var panes = $scope.panes = [];
$scope.select = function(pane) {
angular.forEach(panes, function(pane) {
pane.selected = false;
});
pane.selected = true;
};
this.addPane = function(pane) {
if (panes.length === 0) {
$scope.select(pane);
}
panes.push(pane);
};
}],
templateUrl: 'my-tabs.html'
};
})
.directive('myPane', function() {
return {
require: '^^myTabs',
restrict: 'E',
transclude: true,
scope: {
title: '@'
},
link: function(scope, element, attrs, tabsCtrl) {
tabsCtrl.addPane(scope);
},
templateUrl: 'my-pane.html'
};
});
Upvotes: 0
Reputation: 3975
Here's one way you could potentially get the data into your child DDO. Let me know if any of this is unclear, hope this helps.
function exampleController($scope) {
$scope.data = [
'cupidatat',
'laboris',
'minim',
'nisi',
'anim',
'id',
'laboris'
];
}
function exampleParentDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="parent-example"></div>'
//optionally you could potentially use the child
//directive in the template of this DDO.
//template: '<div class="parent-example"><example-directive data="data"></example-directive></div>'
};
}
function exampleDirective() {
return {
restrict: 'E',
scope: {
data: '='
},
template: '<div class="child-example" ng-repeat="ipsum in data track by $index" ng-bind="ipsum"></div>',
link: function($scope) {
//link function not need unless you need other processing done in child directive.
}
};
}
angular
.module('app', [])
.controller('exampleController', exampleController)
.directive('exampleParentDirective', exampleParentDirective)
.directive('exampleDirective', exampleDirective);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div class="container" ng-app="app">
<div class="row" ng-controller="exampleController">
<example-parent-directive data="data"></example-parent-directive>
<example-directive data="data"></example-directive>
</div>
</div>
Upvotes: 0