And*_*cci 1 portal angular angular-cdk
我有以下服务
@Injectable()
export class PService {
private loadPComponent: ComponentPortal<PComponent>;
private bodyPortalHost: DomPortalHost;
constructor(private appRef: ApplicationRef,
private componentFactoryResolver:
ComponentFactoryResolver,
private injector: Injector) {
this.loadPComponent = new ComponentPortal(PComponent);
}
instance(elementRef: Element) {
this.bodyPortalHost = new DomPortalHost(elementRef,
this.componentFactoryResolver, this.appRef, this.injector);
}
show() {
const componentRef: ComponentRef<PComponent> =
this.bodyPortalHost.attach(this.loadPComponent);
}
hide() {
this.bodyPortalHost.detach();
}
}
Run Code Online (Sandbox Code Playgroud)
因此,我有一个名为“PComponent”的组件,并且从该服务中动态创建该组件,该类有两个方法实例 - 传递调用服务显示的组件的元素 - 附加已“创建”的 PComponent
一切正常,Portal 是一个很棒的解决方案!但我的 PComponent 有一个带有一些变量的 HTML 模板,例如,
{{ 图像URL }}
这应该是一个图像 url 并将该图像显示到 PComponent 中的 div 内容中。 问题 我如何将 imageURL 字符串传递到服务或组件中?
提前致谢
This is the answer
this is the Pcomponent code, this component should be created dinamically from another component. p.component.ts
@Component({
selector: 'app-p',
templateUrl: './p.component.html',
styleUrls: ['./p.component.css']
})
export class PComponent implements OnInit {
name: string = '';
constructor(@Inject(CONTAINER_DATA) public componentData: any) {
}
ngOnInit() {
console.log(this.componentData.data.test);
}
}
Run Code Online (Sandbox Code Playgroud)
so we have to inject the CONTAINER_DATA InjectionToken, from that variable is possible to get the data passed from other components. The CONTAINER_DATA variable is created in the service file. p.service.ts
import {ApplicationRef, ComponentFactoryResolver, ComponentRef, Injectable, InjectionToken, Injector} from '@angular/core';
import {CONTAINER_DATA, PComponent} from './p.component';
import {
ComponentPortal,
DomPortalHost, PortalInjector
} from '@angular/cdk/portal';
export const CONTAINER_DATA = new InjectionToken<{}>('CONTAINER_DATA');
@Injectable()
export class PService {
private loadPComponent: ComponentPortal<PComponent>;
private bodyPortalHost: DomPortalHost;
constructor(private appRef: ApplicationRef,
private componentFactoryResolver: ComponentFactoryResolver,
private injector: Injector) { }
instance(elementRef: Element, data) {
this.loadPComponent = new ComponentPortal(PComponent, null,
this.createInjector({data}));
this.bodyPortalHost = new DomPortalHost(elementRef,
this.componentFactoryResolver, this.appRef, this.injector);
}
show() {
const componentRef: ComponentRef<PComponent> =
this.bodyPortalHost.attach(this.loadPComponent);
}
createInjector(dataToPass): PortalInjector {
const injectorTokens = new WeakMap();
injectorTokens.set(CONTAINER_DATA, dataToPass);
return new PortalInjector(this.injector, injectorTokens);
}
hide() {
this.bodyPortalHost.detach();
}
}
Run Code Online (Sandbox Code Playgroud)
So, in the service we use @angular/cdk/portal to get the PComponent instance. the instance() and the show() methods are the methods to call from an external Component. the createInjector() is the method that create the Injector that help us to pass datas to the component ( PComponent ). So it's time to use our service in another component. example.component.ts
@Component({
selector: 'app-example',
templateUrl: './example.component.html',
styleUrls: ['./example.component.css']
})
export class ExampleComponent implements OnInit {
@ViewChild('bpage', {read: ElementRef}) tref: ElementRef;
constructor(private route: ActivatedRoute, private pService:
PService, private contentService: ContentService) { }
ngOnInit() {
Promise.resolve().then(() => {
this.pService.instance(this.tref.nativeElement, {'test':
'prueba'});
}
}
Run Code Online (Sandbox Code Playgroud)
This component have, in the html template a tag like that:
<div #bpage></div>
Run Code Online (Sandbox Code Playgroud)
in this tag should be charged the content coming from the PComponent and injected from PService. In the OnInit method we have to enclose the service call into a Promise, this avoid the following error:
ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null: undefined'. Current value: 'null: testing text'. It seems like the view has been created after its parent and its children have been dirty checked. Has it been created in a change detection hook ?
After a page refresh you will see the content of PComponent automatically generated and published in the bpage tag
hope it help you
归档时间: |
|
查看次数: |
6138 次 |
最近记录: |