I am writing a generic FilterListView
component. Currently when using it you can pass in a TemplateRef
that dictates how each element is displayed, alongside filtering options etc. This works great when used as is, but there is often need of reuse on various pages which makes this cumbersome
Example of how it currently works
<filter-list-view icon='xxx'
[templateRef]="myRef"
[items]="myItems"
[filterPredicate]="filterPredicate">
<ng-template #myRef let-item>
{{ item.Name }}
</ng-template>
</filter-list-view>
How I would like it to work
Ideally I would like to have a service per type of filter (e.g. 'user', 'resource' etc) that specifies how to collect the data, how to filter the items, the component needed to display results (e.g. templateRef) etc
<filter-list-view [filterDefinition]="userFilterService"></filter-list-view
Where UserFilterService
might look like this:
export class UserFilterService implements IFilterService<T>
{
icon: string;
items: T[];
dataCollection: Promise<T[]>;
filterPredicate: (T) => boolean;
resultComponent: any; // this would hold the TYPE of the component used for display
}
What I am struggling with, is a way to either create a TemplateRef
dynamically to use in lieu of #myRef
which is passed in to templateRef
in the first example.
Ideally UserFilterService
would, create or provide a TemplateRef
to FilterListView
to allow it to render results dynamically.
What have I tried? Dynamic TemplateRef.
I initially tried to create a TemplateRef dynamically using this but it just didnt work. In this case I get an odd error
BrowserModule has already been loaded. If you need access to common directives such as NgIf and NgFor from a lazy loaded module, import CommonModule instead.
This error points to line 45 in the template compiler in the stackblitz referenced above. That is called by my code here.
var html = `<my-item-result [myBinding]="item"></my-item-result>`;
var ref = this.templateCompiler.compile(html, [MyItemResultModule])
ref.subscribe(
x => {
debugger;
this.itemTemplate = x;
},
err => {
console.error(err);
});
I have BrowserModule only listed once in my app, and that is in the main entry module to the app. So this seems odd?
What have I tried? Dynamic Components.
Then I tried switching tactic, instead trying to create the Component directly, and attaching it to an ng-template within my FilterListView.html as per this answer. This worked for the most part, but I couldnt get the component I created to bind to the let-item within the host ng-template.