Создание углового динамического компонента НЕ работает при ПРОИЗВОДСТВЕ - PullRequest
0 голосов
/ 18 мая 2018

У меня проблема с динамическим рендерингом компонента с помощью ' ViewContainerRef ' в элементе гридстера.

Я реализовал компонент, который принимает ссылку на компонент, входы и выходы в качестве входных данных и создает этоданный компонент внутри себя.

ex: <app-component-loader [compRef]="{ref: ExComponent}"><app-component-loader>

внутри загрузчика компонента при обратном вызове onInit У меня есть

if (this.compRef && this.compRef.ref) {
        this._componentFactory = this._componentFactoryResolver.resolveComponentFactory(this.compRef.ref);

        const instance  = this.viewContainer.createComponent(this._componentFactory, 0).instance;

        console.log(instance);

        if (this.compInputs) {
            Object.getOwnPropertyNames(this.compInputs).forEach(field => {
                instance[field] = this.compInputs[field];
            });
        }

        if (this.compOutputs) {
            Object.getOwnPropertyNames(this.compOutputs).forEach(field => {
                instance[field].subscribe(e => {
                    this.compOutputs[field]();
                });
            });
        }
    }

Я использую этот компонент загрузки в компонент элемента гридстера, например:

<gridster [options]="gridsterConfig">
            <gridster-item [item]="widget" *ngFor="let widget of board.widgets">
                <app-component-loader [compRef]="{ ref: registry.get(widget.outletComponent) }" [compInputs]="{ widget: widget }" [compOutputs]="{ removeCallback: widgetRemoveCallback.bind(this), changed: widgetChanged.bind(this) }"></app-component-loader>
            </gridster-item>
 </gridster>

Он работает нормально и загружает элементы гридстера и их компоненты розеток, в то время как разрабатывает .

Hovewer Сегодня я пытался создать свое приложение с ng build --prod и развернутьна сервере я узнаю, что мой загрузчик компонентов не создает компоненты.

Мне не хватает чего-то особенного при создании динамических компонентов для производственных сборок.Я искал об этом, но ничего не получил.

Прежде чем приступить к реализации компонента загрузчика компонентов, я делал это создание компонента с пакетом ng-dynamic-component и снова он работал нормально, пока развивается , но есть исключение, в котором говорится, что экземпляр компонента равен NULL, когда production .

Я думаю, что не проблема в том, что способ создания рендеринга компонентов нуждается в помощи.

Кроме того, мои зависимости:

"@angular/animations": "^5.2.9",
"@angular/cdk": "^6.0.2",
"@angular/common": "^5.2.9",
"@angular/compiler": "^5.2.9",
"@angular/core": "^5.2.9",
"@angular/flex-layout": "^5.0.0-beta.14",
"@angular/forms": "^5.2.9",
"@angular/http": "^5.2.9",
"@angular/platform-browser": "^5.2.9",
"@angular/platform-browser-dynamic": "^5.2.9"

"@angular/cli": "^1.7.3",
"@angular/compiler-cli": "^5.2.9",
"@angular/language-service": "^5.2.9",

Спасибо всем.

1 Ответ

0 голосов
/ 24 мая 2018

Это то, что работает для меня, создайте директиву для просмотра, как показано ниже, в вашем app-component-loader.ts onInIt

@ViewChild(DynamicHostDirective) 
   hostDirective: DynamicHostDirective

ngOnInIt(){
if (this.compRef && this.compRef.ref) {
        this._componentFactory = this._componentFactoryResolver.resolveComponentFactory(this.compRef.ref);

        const instance  = this.hostDirective.viewContainerRef.createComponent(this._componentFactory).instance;

        console.log(instance);

        if (this.compInputs) {
            Object.getOwnPropertyNames(this.compInputs).forEach(field => {
                instance[field] = this.compInputs[field];
            });
        }

        if (this.compOutputs) {
            Object.getOwnPropertyNames(this.compOutputs).forEach(field => {
                instance[field].subscribe(e => {
                    this.compOutputs[field]();
                });
            });
        }
    }
    }

В вашем app-component-loader.html,

<ng-template dynamic-host></ng-template>

наконец, директива хоста

import {Directive, ViewContainerRef} from '@angular/core';

@Directive({
  selector: '[dynamic-host]',
})
export class DynamicHostDirective {
constructor(public viewContainerRef: ViewContainerRef){}
}

Надеюсь, это поможет

...