Reputation: 115
im currently trying to build a component which gets an object with specifications which directive it should render.
So this is my angular component componentRenderer.js
angular
.module('app.core')
.component('componentRenderer', {
templateUrl: '/component-renderer/component-renderer.tpl.html',
controller: ComponentRendererController,
bindings: {
data: '='
}
});
function ComponentRendererController($scope, $element, $timeout, $compile) {
var vm = this;
// Called when component is ready
vm.$onInit = function () {
if (vm.data.type !== 'plain') {
var html = '<' + vm.data.type + ' ';
if (vm.data.hasOwnProperty('options')) {
angular.forEach(vm.data.options, function (value, key) {
if(typeof value === 'object') {
html += (key+'="value" ');
} else {
html += (key+'="'+value+'" ');
}
});
}
html += '></' + vm.data.type + '>';
var el = $compile(html)($scope);
$element.find('.widget__content').append(el);
}
};
}
/component-renderer/component-renderer.tpl.html:
<div class="widget">
<div class="widget__header">
<h2>{{ $ctrl.data.title }}</h2>
</div>
<div class="widget__content">
<h3>{{ $ctrl.data.subtitle }}</h3>
</div>
A data object can for example look like that:
{
"type": "activity-widget",
"options": {
"type": "simple",
}
"title": "Activity"
}
My componentRenderer should now build up the corresponding html, so that the following result will be possible:
<activity-widget type="simple"></activity-widget>
So the options of that previously shown object should be rendered as attributes of the component. Finally the activity-widget component should render the final html construct.
deviceActivity.js
angular
.module('app.core')
.component('deviceActivity', {
templateUrl: '/device-activity/device-activity.tpl.html',
controller: DeviceActivityController,
bindings: {
data: "="
}
});
Until here everything works as expected! But no i want to be able to use options as object too.
{
"type": "activity-widget",
"options": {
"jsonObject": {
"surveillance": [
{
"name": "location",
"value": 25,
"max": 100
},
{
"name": "reporting",
"value": 58,
"max": 80
},
{
"name": "reporting",
"value": 9,
"max": 120
}
]
}
},
"title": "Activity"
}
My componentRenderer should now build up the corresponding html, so that the following result will be possible:
<activity-widget object="jsonObject"></activity-widget>
Sadly its not working, it is not binding the jsonObject to my component. I don't know what im doing wrong...Any help is greatly appreciated!
Thanks in advance!
Upvotes: 0
Views: 83
Reputation: 4456
So you would like to get this
<activity-widget object="jsonObject"></activity-widget>
Instead, here is what is being generated:
<activity-widget jsonObject="value"></activity-widget>
(which exactly corresponds to what componentRenderer.js
should output given the code that it contains)
And the widget that is being generated doesn't work apparently for 2 reasons:
If you insist that this is indeed what you'd like to get
<activity-widget object="jsonObject"></activity-widget>
given the object that you specified, here is how you should change componentRenderer.js
:
angular.forEach(vm.data.options, function (value, key) {
if(typeof value === 'object') {
// providing attribute=value pair correctly
html += ('object="' + key + '" ');
// adding object's value to the scope
// so that it is passed to the widget during compile below
$scope[key] = value;
} else {
html += (key+'="'+value+'" ');
}
});
Notice that this way you can have only one attribute of object type per widget (all other will be overwritten).
Try changing your code like shown above, for me it seem to work fine. If it still doesn't work for you, please create a fiddle (actually, it is what you should have done in the first place for this kind of question)
Upvotes: 1