Reputation: 1148
I'd like to pass a custom template, via bindings, into an AngularJS Component and render it using his scope. Something like this (pseudo-code, this is not working):
angular
.module('myApp', [])
.controller('mainController', ($scope) => {
$scope.getTemplate = () => (`
<div>
<span>{{$ctrl.name}}</span>
</div>
`)
})
.component('myComponent', {
controller: ($scope, $compile) => {
const $ctrl = $scope.$ctrl;
$ctrl.$onInit = () => {
$ctrl.name = 'Hello World!';
};
$ctrl.compileTemplate = () => $compile($ctrl.template())($scope);
},
bindings: {
template: '&'
},
template: `
<div>
My dynamic content: {{$ctrl.compileTemplate()}}
</div>
`
});
Usage:
<div ng-controller="mainController as $ctrl">
<my-component template="$ctrl.getTemplate()"></my-component>
</div>
Expected Result:
<div>
My custom content:
<div>
<span>Hello World!</span>
</div>
</div>
Is there any way to do it?
Upvotes: 2
Views: 3099
Reputation: 1303
In case you want dynamic template, You can utilize the fact that you can pass a function to component template
, in components that function is injectable, I refer you to this question for more info, but here is the main idea:
angular
.module('myApp', [])
.factory('tempalteFactory', {
return getTemplate() {
retrun '<b> yep </b>';
}
})
.component('myComponent', {
controller: ($scope, $compile) => {
const $ctrl = $scope.$ctrl;
$ctrl.$onInit = () => {
$ctrl.name = 'Hello World!';
};
},
template: function($element, $attrs, templateFactory) {
'ngInject';
return templateFactory();
}
});
Upvotes: 1
Reputation: 9800
You can use the $compile
service to create a directive to handle the DOM manipulation involved.
The following working snippet implements an attribute directive compile
which compiles the input value of the attribute in the controller scope. It basically take your template and add it to the inner content of the element to which the directive is attached and finally compiles it.
angular.module('app', [])
.run(($rootScope) => {
$rootScope.name = 'world';
$rootScope.template = `
<label>Name</label>
<input type="text" ng-model="name">
<h2>Hello {{ name }}!</h2>
`;
})
.directive('compile', ($compile) => {
return (scope, element, attrs) => {
scope.$watch(
scope => scope.$eval(attrs.compile),
value => {
element.html(value);
$compile(element.contents())(scope);
}
);
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.5/angular.js"></script>
<div ng-app="app">
<div compile="template"></div>
</div>
Upvotes: 0