gpt4 book ai didi

typescript - 如何通过 typescript 代码动态注入(inject) Angular2 子组件?

转载 作者:太空狗 更新时间:2023-10-29 17:10:16 25 4
gpt4 key购买 nike

上下文 - 我正在尝试创建一个可以包含多个组件的自定义下拉列表。我可以通过 <ng-content> 来完成这个标签,但我的团队固执地坚持认为他们不喜欢那样。他们希望能够几乎完全通过 typescript 代码来实例化这个下拉菜单。

我认为我可以通过 DynamicComponentLoader 完成此操作,但不幸的是,我找到的所有优秀教程都使用了 loadIntoLocation() 函数,该函数现已消失。因此,我尝试使用 loadAsRoot() 函数,但它不起作用。

这是我正在尝试做的事情:

主要.ts:

import { Component } from '@angular/core';
import { MyDropdown } from './MyDropdown';

@Component({
selector: 'my-app',
template: `
<my-dropdown [contentModels]="dropdownContentModels"></my-dropdown>
`
})
export class Main {
dropdownContentModels: any[];
constructor() {
var someComponentModel = {selector: 'some-component', text: 'some'};
var otherComponentModel = {selector: 'other-component', text: 'other'};
this.dropdownContentModels = [someComponentModel, otherComponentModel];
}
}

MyDropdown.ts:

import { Component } from '@angular/core';
import { InjectComponent } from './InjectComponent';

@Component({
selector: 'my-dropdown',
inputs: ['contentModels'],
directives: [InjectComponent],
template: `
<div class="btn-group" dropdown>
<button type="button" dropdownToggle>My Dropdown</button>
<div class="dropdown-menu" role="menu">
<inject-component *ngFor="let item of contentModels" [model]="item"></inject-component>
</div>
</div>
`
})
export class MyDropdown {
contentModels: any[];
}

注入(inject)组件.ts:

import { Component, DynamicComponentLoader, Injector } from '@angular/core';

@Component({
selector: 'inject-component',
inputs: ['model'],
template: `
<div #toreplace></div>
`,
providers: [DynamicComponentLoader, Injector]
})
export class InjectComponent {
model: any;
constructor(private dcl: DynamicComponentLoader, private injector: Injector) {}
ngOnInit() {
this.dcl.loadAsRoot(this.createWrapper(), '#toreplace', this.injector);
}
createWrapper(): any {
var model = this.model;
@Component({
selector: model.selector + '-wrapper',
template: '<' + model.selector + ' [model]="model"></' + model.selector + '>'
})
class Wrapper {
model: any = model;
}

return Wrapper;
}
}

但我收到运行时异常“EXCEPTION: Error: Uncaught (in promise): Can only add to a TokenMap!Token: Injector”

更新! (感谢 echonax):

注入(inject)组件.ts:

import { Component, ComponentResolver, ViewChild, ViewContainerRef, 
ComponentFactory, ComponentRef } from '@angular/core';

@Component({
selector: 'inject-component',
inputs: ['model'],
template: `
<div #toreplace></div>
`
})
export class InjectComponent {
model: any;
@ViewChild('toreplace', {read: ViewContainerRef}) toreplace;
componentRef: ComponentRef<any>;

constructor(private resolver: ComponentResolver) {}

ngOnInit() {
this.resolver.resolveComponent(this.createWrapper()).then((factory:ComponentFactory<any>) => {
this.componentRef = this.toreplace.createComponent(factory);
});
}
createWrapper(): any {
var model = this.model;
@Component({
selector: model.selector + '-wrapper',
directives: [ model.directives ],
template: '<' + model.selector + ' [model]="model"></' + model.selector + '>'
})
class Wrapper {
model: any = model;
}

return Wrapper;
}
}

最佳答案

您可以使用新的 .createComponent() 函数。

import {ComponentRef, Injectable, Component, Injector, ViewContainerRef, ViewChild,ComponentResolver, DynamicComponentLoader} from '@angular/core';

export class InjectComponent {
@ViewChild('toreplace', {read: ViewContainerRef}) toreplace;


constructor(private dcl: DynamicComponentLoader, injector: Injector,private resolver: ComponentResolver) {}

...

    this.resolver.resolveComponent((this.createWrapper()).then((factory:ComponentFactory<any>) => {
this.cmpRef = this.theBody.createComponent(factory)
});

并删除 providers: [DynamicComponentLoader, Injector]

这是一个使用 DynamicComponentLoader(在 app.component.ts 中)的示例 plunker:https://plnkr.co/edit/azoGdAUvDvCwJ3RsPXD6?p=preview

关于typescript - 如何通过 typescript 代码动态注入(inject) Angular2 子组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37618222/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com