7 угловых динамических инъекционных шаблонов - PullRequest
0 голосов
/ 23 апреля 2019

Я постараюсь объяснить мою проблему как можно проще:

  1. В настоящее время я использую NgxDatatable для рендеринга таблицы crud.
  2. У меня есть базовый компонент с именем CrudComponent для обработки всего грубого
  3. Этот компонент должен был быть расширен для всех простых сущностей

Проблема, с которой я сейчас сталкиваюсь, заключается в предоставленииспособ для потомков каким-либо образом ввести пользовательский cellTemplate.

Я пытаюсь избежать дублирования кода, поэтому мне не нужно заново копировать родительский шаблон, просто чтобы добавить 1-2 ng-template.

Например, у меня есть в CrudComponent:

    @ViewChild('actionsCellRenderer') actionsCellRenderer: TemplateRef<any>;

И в шаблоне:

    <ng-template #actionsCellRenderer let-row="row" let-value="value">
        <button mat-icon-button (click)="startEdit(row)">
            <fa-icon [icon]="['far', 'edit']"></fa-icon>
        </button>
        <button mat-icon-button (click)="startDelete(row)" color="warn">
            <fa-icon [icon]="['far', 'trash-alt']"></fa-icon>
        </button>
    </ng-template>

И скажем, я расширил это CrudComponent сMovieComponent.Мне нужно было бы вручную скопировать весь HTML-шаблон в новый MovieComponent.html шаблон и добавить:

    @ViewChild('ratingCellRenderer') ratingCellRenderer: TemplateRef<any>;
    <ng-template #ratingCellRenderer let-row="row" let-value="value">
        <bar-rating
                [(rate)]="value"
                [max]="10"
                theme="horizontal"
                readOnly="true"
        ></bar-rating>
    </ng-template>

Возможные решения:

  1. Одним из решений этой проблемы было бы использование какого-либо прекомпилятора шаблона, например twig.Это вообще возможно?Если да, то как?
  2. Или более угловое решение.В основном таблица из TemplateRef<any> примерно такая:
cellRenderers = {
   rating: new TemplateRef<any>(), //but how do I manually create TemplateRef?
   picture: new TemplateRef<any>(),
}

Затем в NgxDatatable определение столбцов:

{name: 'Score', prop: 'score', cellTemplate: this.cellRenderers['rating']},
ИЛИ, может быть, есть другой, более элегантный способ справиться с этим?

1 Ответ

0 голосов
/ 30 апреля 2019

В итоге я удалил NgxDatatable и написал свою собственную реализацию CrudTable, которая имеет ColumnRendererComponent:

import {Component, ComponentFactoryResolver, Input, OnInit, ViewChild, ViewContainerRef} from '@angular/core';
import {TableColumnType} from '../Table/TableColumnType';
import {FieldConfig} from '../../../Interface/FieldConfig';
import {RendererInterface} from './RendererInterface';
import {PlainRenderer} from './PlainRenderer';
import {FunctionRenderer} from './FunctionRenderer';

@Component({
    selector: 'column-renderer',
    template: `<ng-template #renderer></ng-template>`
})
export class ColumnRendererComponent implements OnInit {
    @Input() public value: any;
    @Input() public row: any;
    @Input() public column: FieldConfig;
    @Input() public columnType: TableColumnType;

    constructor(
        protected componentFactoryResolver: ComponentFactoryResolver,
        public viewContainerRef: ViewContainerRef
    ) {
    }

    ngOnInit(): void {
        this.loadRenderer();
    }

    loadRenderer() {
        let component = this.columnType.template ? this.columnType.template :
            (this.columnType.renderFn ? FunctionRenderer : PlainRenderer);
        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);

        let viewContainerRef = this.viewContainerRef;
        viewContainerRef.clear();

        let componentRef = viewContainerRef.createComponent(componentFactory);
        let instance = <RendererInterface>componentRef.instance;
        instance.column = this.column;
        instance.columnType = this.columnType;
        instance.row = this.row;
        instance.value = this.value;
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...