@ViewChildren получает неопределенные значения
У меня есть библиотека веб-компонентов (пользовательских элементов), которые я собираюсь использовать в других приложениях angular. Проблема в том@ViewChildren()
получение неопределенных значений, невозможность доступа к дочерним элементам внутри моего компонента.
я использую @ViewChildren
потому что я использую encapsulation: ViewEncapsulation.ShadowDom
. Я пробовал использовать@ContentChildren
и это работает, но как только я использую свои компоненты в другом приложении, @ContentChildren
больше не работает (из-за ShadowDom).
Вот минимальный фрагмент кода, чтобы показать проблему. Полный код можно получить здесь
Родительский компонент:
custom-accordion.component.ts
export class CustomAccordionComponent implements AfterViewInit {
@ContentChildren(CustomAccordionContentComponent) contentChildren: QueryList<CustomAccordionContentComponent>;
@ViewChildren(CustomAccordionContentComponent) viewChildren: QueryList<CustomAccordionContentComponent>;
setOpen() { this.open = true; }
toggle() {
console.log("toggle from accordion called...");
this.setOpen();
}
constructor(public elementRef: ElementRef, private renderer2: Renderer2) { }
ngAfterViewInit(): void {
console.log("Content children:", this.contentChildren);
console.log("View children:", this.viewChildren);
}
}
custom-accordion.component.html
примечание: если я использую
<div>
<app-custom-accordion-content></app-custom-accordion-content>
</div>
Я могу видеть @VIewChildren
но данные не отображаются. Поэтому я использую приведенный ниже код, чтобы увидеть отображаемые данные.
<div>
<ng-content></ng-content>
</div>
Дочерний компонент
custom-accordion-content.component.ts
export class CustomAccordionContentComponent implements OnInit {
private _contentId: number;
private _header: string;
private _opened: boolean = false;
private _clickFocus: boolean = true;
private _hideHR: boolean = false;
@Input() isopen: boolean;
@Input() set contentId(value: number) { this._contentId = value; }
get contentId(): number { return this._contentId; }
@Input('header') set header(value: string) { this._header = value; }
get header(): string { return this._header; }
@Output() toggleAccordion: EventEmitter<boolean> = new EventEmitter();
toggleOpen($event: any) {
this.opened = !this.opened;
$event.preventDefault();
this.toggleAccordion.emit(this.opened);
}
keyUp($event: KeyboardEvent) {
$event.preventDefault();
if ($event.keyCode === 32 || $event.keyCode === 19) {
this.toggleAccordion.emit(this.opened);
}
}
// other SETTERS AND GETTERS of private variables
constructor(public elementRef: ElementRef) { }
ngOnInit() { }
}
custom-accordion-content.component.html
<div #accordion class="accordion" [class.selected]="opened" [class.click-focus]="clickFocus" tabindex="{{contentId}}"
(keyup)="keyUp($event)" (click)="toggleOpen($event)">
<div class="accordion-panel add-padding row">
<div class="header col-10">
{{header}}
</div>
<div class="chevron col-2">
<svg class="chevron" width="17px" height="9.5px" viewBox="0 0 17 10" version="1.1"
xmlns="http://www.w3.org/2000/svg">
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<polyline id="Path" stroke="#231F20" stroke-width="2" points="1 1 8.47875354 8.5 15.9575071 1">
</polyline>
</g>
</svg>
</div>
</div>
<div *ngIf="opened" class="accordion-content">
<ng-content></ng-content>
</div>
<hr *ngIf="!hideHR" [class.extend]="opened">
</div>
то у меня есть контейнер, содержащий данные
container.component.html
<div class="form-group w-100">
<app-custom-accordion>
<app-custom-accordion-content *ngFor="let content of fullContent; let i = index" [header]="content.header"
[isopen]="content.open" contentId="{{i}}">
<div>
<app-custom-p row="1" col="12" *ngFor="let detail of content.content[0].details" [text]="detail">
</app-custom-p>
<app-custom-p row="2" col="12" [text]="content.content[0].footer"></app-custom-p>
</div>
</app-custom-accordion-content>
</app-custom-accordion>
</div>
Я пытался решить эту проблему, но безуспешно. Я просто хочу получить значения, которые @ContentChildren получает с @ViewChildren. Любая помощь будет оценена.