Issue
I’m trying to use ng-content
to selectively display certain components in certain areas, but I’m not getting the filtering to work correctly.
I have a layout component which contains certain components which are marked with directives where they need to render.
<standard-layout class="blah">
<sample-navigation *navBarItem></sample-navigation>
<sample-navigation *navBarItem></sample-navigation>
<sample-form-1 *contentItem></sample-form-1>
<sample-form-2 *contentItem></sample-form-2>
<sample-form-3 *contentItem></sample-form-3>
<sample-navigation *actionBarItem></sample-navigation>
<sample-navigation *actionBarItem></sample-navigation>
</standard-layout>
This is my contentItem
directives:
@Directive(selector: '[contentItem]')
class ContentItemDirective implements AfterContentInit {
final ViewContainerRef vcRef;
final TemplateRef template;
final ComponentResolver componentResolver;
ContentItemDirective(this.vcRef, this.template, this.componentResolver);
ComponentRef componentRef;
@override
ngAfterContentInit() async {
final componentFactory =
await componentResolver.resolveComponent(ContentItem);
componentRef = vcRef.createComponent(componentFactory);
(componentRef.instance as ContentItem)
..template = template;
}
}
This is what my ContentItem
looks like
@Component(
selector: "content-item",
host: const {
'[class.content-item]': true,
},
template: """
<template [ngTemplateOutlet]="template"></template>
""",
directives: const [NgTemplateOutlet]
)
class ContentItem {
TemplateRef template;
}
Inside the standard-layout
‘s template, when I do <ng-content select=""></ng-content>
, it displays all the components as expected.
When I try and filter the components, it doesn’t seem to work:
CSS Filtering displays nothing:
<ng-content select=".content-item"></ng-content>
Filtering on the content-item
tag itself display nothing either:
<ng-content select="[content-item]"></ng-content>
I’ve tried many permutations of the select=...
and just can’t seem to get it working. Any ideas?
I’m on the Angular Dart 3.0.0 package.
Solution
Managed to get it working using @ContentChildren
Inside my StandardLayout
component, I filtered the inputs using:
@ContentChildren(ContentItemDirective)
QueryList<ContentItemDirective> contentItems;
@ContentChildren(ActionBarItemDirective)
QueryList<ActionBarItemDirective> actionBarItems;
@ContentChildren(NavBarItemDirective)
QueryList<NavBarItemDirective> navBarItems;
Now inside the standard-layout
template, can loop through the items and display the template using ngTemplateOutlet
<nav class="nav1" #nav1>
<div *ngFor="let item of navBarItems">
<template [ngTemplateOutlet]="item.template"></template>
</div>
</nav>
<div class="content" #content>
<div *ngFor="let item of contentItems">
<template [ngTemplateOutlet]="item.template"></template>
</div>
</div>
<nav class="nav2" #nav2>
<div *ngFor="let item of actionBarItems">
<template [ngTemplateOutlet]="item.template"></template>
</div>
</nav>
Answered By – Jan Vladimir Mostert
Answer Checked By – Gilberto Lyons (FlutterFixes Admin)