动态组件未加载到专利组件内部

时间:2019-02-27 00:22:24

标签: angular angular-dynamic-components

基于下面的JSON对象,我正在根据其类型创建动态组件。

          {

            "type": "paragraph",

            "depth": 1,

            "text": "This is paragraph",

            "inlineStyleRanges": [],

            "inlineEntityRanges": [

              {

                "type": "LINK",

                "offset": 83,

                "length": 16,

                "data": {

                  "target": "_self",

                  "url": "/index.htm"

                }

              }

            ]

          }

使用上述结构,我创建了父组件ParagraphComponent,并且如果您发现inlineEntityRanges有一个type,那么我想创建一个LinkComponent

出了什么问题?

LinkComponent已创建但不在其父组件内部    是在ParagraphComponent之外创建的。

<rc-paragraph><p>This is paragraph</p></rc-paragraph>`
<app-link>/index.htm</app-link>

但是实际上应该是这样,

<rc-paragraph>
    <p>This is paragraph <app-link>/index.htm</app-link></p>
</rc-paragraph>

下面是呈现组件的代码,

private renderReactiveContent(content, container: ViewContainerRef) {

    // resolve content['_type'] to factory
    var type: Type<any>;
    if (content instanceof Array) {
      type = this.contentMappings[content[0].type];
    } else {
      type = this.contentMappings[content.type];
    }
    if (!type) {
      return;
      // throw new ReferenceError(`No content mapping for type=${type}`);
    }

    const componentFactory: ComponentFactory<any> = this.componentFactoryResolver.resolveComponentFactory(type);
    const component = container.createComponent(componentFactory, container.length, this.injector);
    console.info('Component dynamically created ', component);

    // content lifecycle hook: notify of new values
    const cmpCreate = asContentCreate(component);
    cmpCreate.contentOnCreate(content);

    // render embedded content
    if (content && Object.keys(content).length > 0) {

      const cmpEmbeddable = asContentEmbeddable(component);
      if (cmpEmbeddable) {

        // render in the target element of ContentEmbeddable
        const childContainer = cmpEmbeddable.contentEmbeddable();

        Object.keys(content).forEach((key: string) => {
          const value = content[key];

          // XX: recursive rendering
          if (value instanceof Array) {
            value.forEach((v) => {
              this.renderReactiveContent(v, childContainer);
            });
          } else {
            this.renderReactiveContent(value, childContainer);
          }
        });

      } else {

        // fatal: embedded content must be hosted by ContentEmbeddable
        const cmpName = component.instance['constructor'].name;
        throw new TypeError([`Trying to render embedded content.`,
          `${cmpName} must implement interface ContentEmbeddable`].join(' '));

      }

    }
    component.hostView.detectChanges();
  }

我在这里做错了,请帮忙。

有效的原型供参考-https://stackblitz.com/edit/angular-qsl9yu?file=src%2Fapp%2Frender%2Fcontent-host.component.ts

1 个答案:

答案 0 :(得分:0)

如果您的主机是

,那么角度注入视图的方式是
<span #container><span>

然后将其注入

<span><span>
<your-injected-view></your-injected-view>

因此,当您尝试注入父对象时,父元素是宿主元素,子元素将被注入到它旁边而不是内部。

如何解决? 一种方法可以是将父级内部的元素设为宿主元素,而不是将父级容器作为宿主。

<parent>
 <span #container></span>
</parent>

因此它将注入为

<parent>
  <span></span>
  <your-injected-view></your-injected-view>
</parent>

使用<ng-container></ng-container>注入视图并避免任何副作用总是很好的。