-
Notifications
You must be signed in to change notification settings - Fork 6.8k
Closed
Labels
Description
Reproduction
I followed the documentation https://beta-angular-material-io.firebaseapp.com/cdk/portal/overview, however this error erupts.
Code
ts
import {
AfterViewInit,
Component, EventEmitter,
InjectionToken, Injector,
Input,
OnDestroy,
OnInit, Output,
ViewContainerRef,
ViewEncapsulation
} from '@angular/core';
import { ComponentPortal, Portal, PortalInjector, TemplatePortal } from '@angular/cdk/portal';
import { Subject } from 'rxjs';
export const PORTAL_DATA = new InjectionToken<{}>('PortalData');
@Component({
selector: 'vimbo-renders-component-or-template-dynamically',
templateUrl: './renders-component-or-template-dynamically.html',
styleUrls: ['./renders-component-or-template-dynamically.scss'],
encapsulation: ViewEncapsulation.None
})
export class VimboRendersComponentOrTemplateDynamicallyComponent implements OnInit, OnDestroy, AfterViewInit {
selectedPortal: Portal<any>;
componentPortal: ComponentPortal<any>;
templatePortal: TemplatePortal<any>;
@Input()
componentName: any;
@Input()
templateName: any;
@Input()
inputData: {
[K: string]: any;
};
@Output()
outputData: EventEmitter<any>;
// Private
private _unsubscribeAll: Subject<any>;
/**
* Constructor
*
* @param {ViewContainerRef} _viewContainerRef
* @param {Injector} injector
*/
constructor(
private _viewContainerRef: ViewContainerRef,
private injector: Injector
) {
// Set the defaults
this.outputData = new EventEmitter();
// Set the private defaults
this._unsubscribeAll = new Subject();
this.selectedPortal = null;
}
// -----------------------------------------------------------------------------------------------------
// @ Lifecycle hooks
// -----------------------------------------------------------------------------------------------------
/**
* On init
*/
ngOnInit(): void {
console.log(this)
}
/**
* After View Init
*/
ngAfterViewInit() {
// INFORMED TWO INPUT, ERROR
if (this.componentName && this.templateName) {
console.error('Only one of the Inputs (componentName, templateName) can be informed');
}
// COMPONENT
else if (this.componentName && !this.templateName) {
this.componentPortal = new ComponentPortal(
this.componentName,
null,
this.createInjector(this.inputData)
);
this.selectedPortal = this.componentPortal;
}
// TEMPLATE HTML
else if (!this.componentName && this.templateName) {
this.templatePortal = new TemplatePortal(
this.templateName,
this._viewContainerRef,
this.createInjector(this.inputData)
);
this.selectedPortal = this.templatePortal;
}
}
/**
* On destroy
*/
ngOnDestroy(): void {
// this.selectedPortal.detach();
// Unsubscribe from all subscriptions
this._unsubscribeAll.next();
this._unsubscribeAll.complete();
}
// -----------------------------------------------------------------------------------------------------
// @ Public methods
// -----------------------------------------------------------------------------------------------------
/**
* Create Injector
* @param data
*/
private createInjector(data): PortalInjector {
const injectorTokens = new WeakMap<any, any>([
[PORTAL_DATA, data],
]);
return new PortalInjector(this.injector, injectorTokens);
}
}html
<ng-template [cdkPortalOutlet]="selectedPortal">
</ng-template>another question, I have an input where the component to be rendered is informed, I would pass the name as a string and within the portal component, resolve based on the name of the component.
If not, I have to reference / import all the components therein within the portal component and pass the name of the component's class.
Environment
Angular CLI: 8.3.20
Node: 10.15.3
OS: linux x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... platform-server, router, service-worker
Package Version
--------------------------------------------------------------------
@angular-devkit/architect 0.803.20
@angular-devkit/build-angular 0.803.23
@angular-devkit/build-optimizer 0.803.20
@angular-devkit/build-webpack 0.803.23
@angular-devkit/core 8.3.20
@angular-devkit/schematics 8.3.20
@angular/cdk 8.2.3
@angular/cli 8.3.20
@angular/flex-layout 8.0.0-beta.27
@angular/material 8.2.3
@angular/material-moment-adapter 8.2.3
@ngtools/webpack 8.3.23
@nguniversal/express-engine 8.2.6
@nguniversal/module-map-ngfactory-loader 8.2.6
@schematics/angular 8.3.20
@schematics/update 0.803.20
rxjs 6.5.3
typescript 3.5.3
webpack 4.39.2
tommyc38
