I have a number of angular 1.5 components that all take the same attributes and data structure. I think they could be re-factored into a single component, but I need a way to dynamically choose a template based upon the interpolated value of the type
attribute.
var myComponentDef = {
bindings: {
type: '<'
},
templateUrl: // This should be dynamic based on interpolated type value
};
angular.module('myModule').component('myComponent', myComponentDef);
I can't use the templateUrl function($element, $attrs) {}
because the values in the $attrs
are uninterpolated so I wouldn't get the type specified in the passed in data.
I could just have one big template with a series of ng-if
or ng-switch
directives, but I would like to keep the templates separate.
Alternatively, I could just keep the components separate and use ng-switch
etc in the parent component, but I don't like this as it seems like a lot of repetition.
I'm looking for a solution where I can use the interpolated type
passed into the bindings to match a template url for each type which will then be used to build the component.
Is this possible?
Thanks
You can simply extend your base component and overwrite the template. This allows you to have different components with the exact same functionality, but different templates.
What dynamic components are. Dynamic means, that the components location in the application is not defined at buildtime. That means, that it is not used in any angular template. Instead, the component is instantiated and placed in the application at runtime.
ComponentFactorylinkBase class for a factory that can create a component dynamically. Instantiate a factory for a given type of component with resolveComponentFactory() . Use the resulting ComponentFactory. create() method to create a component of that type. Deprecated: Angular no longer requires Component factories.
This is not something that components were specially made for. The task narrows down to using a directive with dynamic templates. The existing one is ng-include
.
To use it within a component, it should be:
var myComponentDef = {
bindings: {
type: '<'
},
template: '<div ng-include="$ctrl.templateUrl">',
controller: function () {
this.$onChanges = (changes) => {
if (changes.type && this.type) {
this.templateUrl = this.type + '.html';
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With