How can I add code into my directive with transclude and pass in a parameter in AngularJS?
angularjs
Solution
About transclusion, I advise you to take a look to this section of the doc. In your case, you have to:
- ask for transclusion in the directive definition object
- indicate in the template which element will receive the transcluded elements with the ng-transclude directive
That give us this directive:
app.directive('mySelect', function () {
return {
restrict: "A",
transclude: true,
template: "<div class='select-area'>" +
"<span> </span>" +
"<div ng-transclude></div>" +
"</div>"
};
});
About passing a parameter, you have access to the attributes of the directive on the third parameter of the link function:
app.directive('mySelect', function () {
return {
restrict: "A",
transclude: true,
template: "<div class='select-area'>" +
"<span> </span>" +
"<div ng-transclude></div>" +
"</div>",
link: function (scope, element, attrs) {
}
};
});
Then, if your parameter is always plain text you can access the value directly:
attrs.mySelectArea
Otherwise, if your parameter can be in the scope you can use the $parse service to get its value:
$parse(attrs.mySelectArea)(scope)
To display the value in the template, you have to provide it in the scope:
app.directive('mySelect', function () {
return {
restrict: "A",
transclude: true,
template: "<div class='select-area'>" +
"<span> {{ mySelectArea }} </span>" +
"<div ng-transclude></div>" +
"</div>",
link: function (scope, element, attrs) {
scope.mySelectArea = attrs.mySelectArea;
}
};
Finally, if you want that your directive template replace the element you can use the replace option (more infos):
app.directive('mySelect', function () {
return {
restrict: "A",
transclude: true,
replace: true,
template: "<div class='select-area'>" +
"<span> {{ mySelectArea }} </span>" +
"<div ng-transclude></div>" +
"</div>",
link: function (scope, element, attrs) {
scope.mySelectArea = attrs.mySelectArea;
}
};
I made a plunker of it.
I strongly advise you to to deep dive into the directive guide and the directive API to have a good sight of what can be done with directives.
Problem
I have code like the following that's used in many places in my application and would like to replace some of this HTML with a directive. I realize there is not so much I can replace as the HTML's are so different: ``` <div class="select-area"> <span>Subject</span> <select data-ng-disabled="option.subjects.length == 0" data-ng-model="option.selectedSubject" data-ng-options="item.id as item.name for item in option.subjects"> </select> </div> <div class="select-area" data-ng-hide="utilityService.isNotNumber(option.selectedTopic)"> <span>Subtopic</span> <select data-ng-model="option.selectedSubtopic" data-ng-options="item.id as item.name for item in option.subtopicsPlus"> </select> </div> ``` I would like to use a directive but I am not really sure how to start. I want to use transclude to replace the inside so I was thinking that my directive call would look something like this: ``` <div class="select-area" my-select-area="Subject"> <select data-ng-disabled="option.subjects.length == 0" data-ng-model="option.selectedSubject" data-ng-options="item.id as item.name for item in option.subjects"> </select> </div> <div class="select-area" data-ng-hide="utilityService.isNotNumber(option.selectedTopic)" my-select-area="Subtopic"> <select data-ng-model="option.selectedSubtopic" data-ng-options="item.id as item.name for item in option.subtopicsPlus"> </select> </div> ``` Here's what I have so far: ``` app.directive('mySelect', function () { return { restrict: "A", template: "<div class='select-area'>" + "<span> </span>" + "</div>", }; }); ``` Can someone show me how I can pass in the parameter that goes inside the span and also how I can add transclude? Update: Based on Bastien's answer There were a couple of small syntax errors but based on Bastien's answer I tried the following: ``` app.directive('mySelect', function () { return { restrict: "A", transclude: true, template: "<div class='select-area'>" + "<span> {{ mySelectArea }} </span>" + "<div ng-transclude></div>" + "</div>", link: function (scope, element, attrs) { scope.mySelectArea = attrs.mySelectArea; } } }); ``` Here's my HTML: ``` <div data-my-select myselectarea="Page type"> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes"></select> </div> ``` Here's the HTML it created: ``` <div data-my-select="" myselectarea="Page type"> <div class="select-area"> <span class="ng-binding"> </span> <div ng-transclude=""> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes" class="ng-scope ng-pristine ng-valid"> <option value="0">Edit Basic</option> <option value="1" selected="selected">Edit Standard</option> <option value="2">Report</option> </select> </div> </div> </div> ``` What I really need is for it to create this: ``` <div class="select-area"> <span>Page Type</span> <select data-ng-model="option.selectedPageType" data-ng-options="item.id as item.type for item in option.pageTypes" class="ng-pristine ng-valid"> <option value="0">Edit Basic</option> <option value="1" selected="selected">Edit Standard</option> <option value="2">Report</option> </select> </div> ```