Reputation: 1057
I'm trying to implement a search component being able to trigger a search(term: string)
function on specific children. This search function will return null if the search on the child failed or a reference to the child if succeeded.
This is so because I want to "collect" all references to the angular components that succeeded in a list, so that I could set them somehow as 'new' ContentChildren, so actually do basic filtering..
This is what I have so far:
search.component.html
<input (value)="searchterm" />
<ng-content>
<!-- all components that implements iSearchable here -->
</ng-content>
search.component.ts
...
export class searchComponent implements OnChanges
{
@Output('searchterm')
public searchterm: string;
// 1. Problem: ContentChildren does not work with interfaces?
@ContentChildren(Isearchable)
searchContent: QueryList<Isearchable>
// 2. Problem: ngOnChanges will not fire when searchterm is changed
ngOnChanges(event)
{
var toBeShown = [];
// go through and let the components filter themselves
for(let i = 0; i < this.searchContent.length; i++)
{
var element: Isearchable = this.searchContent[i];
var result = element.search();
if(result != null) // search suceeded
toBeShown.push(element);
}
// 3. Problem: how to get them displayed ?
}
}
Basicly I have 3 problems:
1. The first is that @ContentChildren() won't accept the (yes, imported) interface Isearchable, since '[ts] Cannot find name Isearchable'. Alternatively all Isearchable components also have a common baseclass, but this also do not work.
Currently executing the program gives me the following error: "Uncaught (in promise): Unexpected directive value 'undefined' on the View of component 'SearchComponent'"
2. The second problem is that somehow the ngOnChanges won't be fired even if I type into the input. This must be simple, do I miss something?
3. Finally, the third problem is that I do not know exactly how to make the search results (that can be of different component types) being displayed in the DOM. My hope is actually that I can somehow two-way bind to the @ContentChildren searchcontent. This would probably solve the problem, wouldn't it?
I really don't have a clue, how to continue, any help is appreciated! Thank you all!
Cheers
Upvotes: 2
Views: 3121
Reputation: 202176
You can't use interfaces at this level since they only apply at design time not at runtime.
There is also an error in your code:
@Input('searchterm') // instead of @Output
public searchterm: string;
To get the list of specified components as input, you need to define a base class for your component and use this class in @ContentChildren
. An additional step is required to make this work. You need to register the component itself into its providers against the parent class (with useExisting
). This explanation could appear a bit "abstract" but this question could help you and will give you a concrete sample:
Upvotes: 5