Injection of dynamic directive/component in Angular 2

醉酒当歌 提交于 2019-12-13 15:43:35

问题


I'm new to Angular 2 and thought I'd make an extendable master-detail flow to start learning.

The 'master'-part is working, I can easily plugin the specific service I need to populate the list when bootstrapping the app. The problem lies in making the 'detail'-part extendable.

Basically, the master-detail template has the following lines in the template:

<div class="large-10 columns">
    <detail [item]="masterItemActive" id="detail"></detail>
</div>

No, I could just load the Detail directive and be done with it, but I want that directive/component to be injectable so I could plugin whatever detail directive/component I like without hard-coding it into the 'master-detail'-component.

In order to achieve this I tried the DynamicComponentLoader:

dcl.loadAsRoot(detailComponent, '#detail', injector);

And the constructor of master-detail.component.ts:

constructor(
    dcl:DynamicComponentLoader,
    injector: Injector,
    elementRef:ElementRef,
    detailComponent:BaseDetailComponent

And as part of the bootstrap:

provide(BaseDetailComponent, {useValue: SomeSpecificDetailComponent})

The good news is that this works, it loads the SomeSpecificDetailComponent and shows the template where needed.

But now I'm stuck. Typescript is complaining, I cant seem to access the item passed down via <detail [item]='masterItemActive'> and I have no idea if this pattern is the way to go for finding a solution for this problem.

So my three questions are:

Is the DynamicComponentLoader the way to go to solve this problem?

Because I would much rather provide() a directive which the master-detail uses. This seems the most painless approach but I have no idea how to achieve this.

How can I access the item inside SomeSpecificDetailComponent?

I tried:

@Injectable()
export class SomeSpecificDetailComponent extends BaseDetailComponent {
    @Input()
    item:BaseMasterItem; // always empty (and yes, masterItemActive is being set )
}

And how can I prevent typescript from complaining?

Because the first argument of dcl.loadAsRoot() needs to be of type 'Type' - which it isn't.

Argument of type 'BaseDetailComponent' is not assignable to parameter of type 'Type'

Any help would be much appreciated!

Update

I've been wrongly using Type as an interface, the typescript compilation error was fixed by using BaseDetailComponent extends Type.


回答1:


Binding to dynamically injected components or directives is currently not supported.

What you can do is to pass the data imperatively to the created component

dcl.loadAsRoot(detailComponent, '#detail', injector)
.then(componentRef => componentRef.instance.item = this.masterItemActive);


来源:https://stackoverflow.com/questions/35671321/injection-of-dynamic-directive-component-in-angular-2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!