I'm attempting to create a directive to manage ARIA Web accessible tab events using Angular 2+, but I'm having an issue with Angular Directives.
I want to have hierarchical directives so I can specify the parent and have access to child directives so I can bind the tabindex correctly.
I have a full example on stackblitz if you need to refer to that.
As an example I have 3 directives. AriaListBox, AriaLabel & AriaListItem. AriaListBox is the parent containing an AriaLabel and a collection of AriaListItems.
I have been able to get a reference to the AriaLabel using @ContentChild but cannot do the same with @ContentChildren to get references for the AriaListItem directive.
From the AriaListBox I'm attempting to use the following which I believe should be set in the ngAfterContentInit event following the Angular Documentation.
@ContentChildren(Directive, { descendants: true }) public items: QueryList<Directive>;
AriaListBox
src/aria/aria-listbox.directive.ts
@Directive({
selector: '[AriaListBox]',
})
export class AriaListBoxDirective implements OnInit, AfterContentInit {
@ContentChild(AriaLabelDirective) public label: AriaLabelDirective;
@ContentChildren(AriaListItemDirective, { descendants: true })
public listItems: QueryList<AriaListItemDirective>;
constructor(private el: ElementRef, private searchService: SearchService) {}
public ngAfterContentInit(): void {
console.log('listItems', this.listItems);
}
}
AriaLabel
src/aria/aria-label.directive.ts
@Directive({
selector: '[AriaLabel]',
})
export class AriaLabelDirective {
constructor(public el: ElementRef) {}
}
AriaListItem
src/aria/aria-listitem.directive.ts
@Directive({
selector: '[AriaListItem]',
})
export class AriaListItemDirective {
constructor(public el: ElementRef) {}
}
HTML
src/search-link-list/search-link-list.component.html
My HTML template uses the directives with the following.
<div AriaListBox>
<h3 AriaLabel>{{ title$ | async }}</h3>
<ul>
<li *ngFor="let item of items$ | async">
<a href="{{ item.url }}" #link AriaListItem>{{ item.name }}</a>
</li>
</ul>
</div>
Is there anything I have missed? I have attempted to get a reference using a selector @ContentChildren('AriaListItem') or the same with @ViewChildren(AriaListItemDirective) and similarly @ViewChildren('AriaListItem') But since it's a directive and not a component it also doesn't work.
The items$ are mocked inside the search.service.ts file and are rendered to the screen without any issue.
Edit --
If I inspect the LinkListItemComponent and the ListBoxDirective lifecycle events, I can see that the #link QueryList exists in the SearchLinkListComponent::ngAfterContentInit before the AriaListBoxDirective::ngAfterContentInit, so it seems that the Directive should have access to the content.
Thanks for any help!