I have a component called button-search
which has a dropdown with search options:
<button-search>
<item type="identifier">Identifier</item>
<item type="title">Title</item>
<item type="city">City</item>
<item type="town">Town</item>
<item type="address">Address</item>
<item type="postal">Postal</item>
<item type="divider"></item>
<item type="clear">Clear Search</item>
</button-search>
The item
component is not supposed to render anything directly and is rather for passing complex params into the button-search
component so that the button-search
component can render those dropdown items the way it should be rendered.
Item
is defined as follow:
@Component(
selector: 'item',
template: '')
class Item {
@Input() String type = "type-goes-here";
}
ButtonSearch
is defined as follow:
@Component(
selector: 'button-search',
directives: const[Item],
template: '''
... enormous template ...
''')
class ButtonSearch {
ButtonSearch(@ViewChildren(Item) QueryList<Item> items){
print(items);
}
}
Instead of seeing a list of 9 items being printed to the console, all I'm seeing is []
.
I've tried using a String param instead of an object, but it still gives me null.
ButtonSearch(@ViewChildren('item') QueryList<Item> items){
What am I missing to make @ViewChildren
get all the items and print something other than []
Is there something special that needs to be done to get the text between <item>
and </item>
or will @ViewChild
work for that ?
Update: Changing the template to include <ng-content></ng-content>
:
template: '''
<ng-content></ng-content>
... enormous template ...
''')
I can see the following being printed in the browser as part of the button-search
component:
Identifier, Title, City, Town, Address, Postal, Clear Search
So at least I know the page I'm on does have items in its button-search
component.
It should be
@Component(
selector: 'button-search',
directives: const[Item],
template: '''
<ng-content></ng-content>
... enormous template ...
''')
class ButtonSearch implements AfterContentInit{
@ContentChildren(Item) QueryList<Item> items;
ngAfterContentInit() {
print(items);
}
}
See also https://stackoverflow.com/a/35209681/217408
There is also the @Query()
annotation which allows to constructor-inject references to child elements but it is marked deprecated.
<ng-content>
If you pass "content" as children to your component, then you can query them using @ContentChildren()
instead of @ViewChildren()
. If you want them to be displayed in the DOM you also need to add the <ng-content></ng-content>
tag as a target for the transclusion. You can also have multiple <ng-content></ng-content>
tags where a select=".someCssSelector"
can be used to transclude a subset of content at a specific target location. There should be only one <ng-content></ng-content>
without the select
attribute though. The first without select
will target all content that doesn't match other selectors.
Plunker example
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