#angular #ionic-framework #ngfor #ng-template #ng-container
Вопрос:
Я хочу создать своего рода конструктор страниц для проекта ionic 5. Идея заключается в циклическом переборе массива в шаблоне моей страницы. В этом цикле должна быть возможность загружать различные дочерние компоненты (например, форматы сообщений WordPress). Возможны различные типы шаблонов (например: ионные кнопки, ионная карта, ионные элементы). Для каждого из этих компонентов я создал отдельный компонент. С сервера я получу массив данных. Каждый элемент в этом массиве имеет переменную шаблона, которая должна ссылаться на созданный мной шаблон компонента (как это делает formly с формами). Преимущество этого заключается в том, что порядок компонентов может быть определен сервером.
Я попробую объединить ng-контейнер и ng-шаблон, но не уверен, что это правильный способ, и не знаю, как реализовать это в машинописном тексте страницы. Я буду читать о TemplateRef, ViewChild, ContentChild
том, но не уверен, что и как использовать, и как передавать данные в шаблоны в этом цикле.
Образец данных
this.components = [
{
template: 'buttons', // --> this must load templates/buttons.html
templateOptions: {
cards: [
{ title: "button 1", color: "primary"},
{ title: "button 2", color: "secondary"},
]
}
},
{
template: 'items', // --> this must load templates/items.html
templateOptions: {
listHeader: "List title",
items: [
{ title: "item 1", label: "item 1 label"},
{ title: "item 2", label: "item 2 label"},
]
}
},
{
template: 'cards', // --> this must load templates/cards.html
templateOptions: {
cards: [
{ title: "card 1", content: "content 1"},
{ title: "card 2", content: "content 2"},
]
}
}
];
Шаблон страницы
<ng-container *ngFor="let component of components">
<ng-template
[ngTemplateOutlet]="component?.template"
[ngTemplateOutletContext]="component?.templateOptions"
></ng-template>
</ng-container>
Buttons template
<ion-toolbar>
<ion-buttons>
<ion-button *ngFor="let button of buttons" [color]="button?.color">
{{ button?.title }}
</ion-button>
</ion-buttons>
</ion-toolbar>
Buttons typescript
import { Component, OnInit, Input } from '@angular/core';
@Component({
selector: 'template-buttons',
templateUrl: './buttons.component.html',
styleUrls: ['./buttons.component.scss'],
})
export class templateButtons implements OnInit {
@Input() buttons: any = [];
constructor() { }
ngOnInit() {}
}
Page module
...
import { templateHeader } from "./../../templates/header/header.component";
import { templateButtons } from "./../../templates/buttons/buttons.component";
import { templateCards } from "./../../templates/cards/cards.component";
import { templateItems } from "./../../templates/items/items.component";
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
PageRoutingModule,
SharedModule
],
declarations: [SearchPage, templateHeader, templateButtons, templateCards, templateItems]
})
export class SearchPageModule {}
What works but doesn’t feel the right way is this:
<ng-container *ngFor="let component of components">
<!-- Buttons -->
<template-buttons *ngIf="component?.template == 'buttons'" [buttons]="component?.templateOptions?.buttons"></template-buttons>
<!-- Cards -->
<template-cards *ngIf="component?.template == 'cards'" [cards]="component?.templateOptions?.cards"></template-cards>
<!-- Items -->
<template-items *ngIf="component?.template == 'items'" [cards]="component?.templateOptions?.items"></template-items>
</ng-container>