Reputation: 8248
I have created basic HTML field generator directive called field as like below
app.directive('field',function(){
return {
restrict : "E",
scope : {
fielddata : '='
},
link : function(scope,elem,attr){
var content;
scope.Options = {
id: scope.$id+'_'+elem.attr('id'),
label : elem.attr('label'),
placeholder : elem.attr("placeholder"),
};
scope.contentUrl = 'templates/fields/'+elem.attr('template')+'.html';
},
template: '<div ng-include="contentUrl"></div>'
}
})
I can able to generate fields as like below
<field id="NAME" template="text" label="First Name" placeholder="Enter First Name" fieldData="NAME"></field>
Check this plunker
Extending the functionality to generate element directive itself. Have simple object to setup the field element and use another directive to generate element directive
Controller
app.controller('contactController', ['$scope', 'dataService',function($scope,dataService) {
$scope.message = 'Contact us! . This is just a demo.';
dataService.getContactData().then(function(data) {
$scope.NAME = data.first_name;
$scope.LNAME = data.last_name;
$scope.DESC = data.description;
});
$scope.fields= [
{
elements: [
{
template_name : "text"
id: "NAME",
label: "First Name",
placeholder : "First Name"
}
],
html: '<div ng-repeat="elem in t.elements"><field id="{{elem.id}}" template="{{elem.template_name}}" label="{{elem.label}}" placeholder="{{elem.placeholder}}"" fieldData="{{elem.id}}" ></field></div>'
}
];
}]);
app.directive("bindCompiledHtml", function($compile, $timeout) {
return {
template: '<div></div>',
scope: {
rawHtml: '=bindCompiledHtml'
},
link: function(scope, elem, attrs) {
scope.$watch('rawHtml', function(value) {
if (!value) return;
var newElem = $compile(value)(scope.$parent);
elem.contents().remove();
elem.append(newElem);
});
}
};
});
});
Say contact.html
<div ng-repeat="t in fields" bind-compiled-html="t.html"></div>
My issue is, bindCompiledHtml Directive generate elements and calling field directive as expected but it value is not get parsed. Setting Break point from field directive link function gives elem as below
[
<field id="{{elem.id}}" template="{{elem.template_name}}" label="{{elem.label}}" placeholder="{{elem.placeholder}}" class="ng-isolate-scope">
<!-- ngInclude: contentUrl -->
</field>
]
and console gives following error
/templates/fields/%7B%7Belem.template_name%7D%7D.html 404 (Not Found)
To see 404 Please check this plunker console
How do we call field directive once all its value get parsed with isolate scope ? Please advice
Upvotes: 0
Views: 105
Reputation: 6173
Dinesh, without a given original problem your code is rather over complicated. That is why I was asking about the purposes of these nested compilations.
The trouble you experience in current code is the definition of directive. Once it's attributes are not defined in isolated scope via =
their values will never be evaluated and will always remain plain text. That is why you can't use expressions in ng-repeat
like {{t.template_name}}
when you define values for attributes of your field
directive. Directive should have the following implementation
app.directive('field', function() {
return {
restrict: "E",
scope: {
placeholder: '=',
label: '=',
id: '=',
template: '='
},
link: function(scope, elem, attr) {
var content;
scope.Options = {
id: scope.$id + '_' + scope.id,
label: scope.label,
placeholder: scope.placeholder
};
scope.contentUrl = scope.template + '.html';
},
template: '<div ng-include="contentUrl"></div>'
}
});
As a result you will always have to define an expression to these attributes. Thus in 'manual' markup you would use "'my text'"
instead of "my text"
<field id="NAME" template="'text'" label="'First Name'"
max-size="40" placeholder="'Enter First Name'"
type="edit" ></field>
Updated plunker
Upvotes: 1