【问题标题】:Angular 7 Dynamic Content ProjectionAngular 7 动态内容投影
【发布时间】:2023-03-23 09:19:02
【问题描述】:

我需要能够告诉一个角度组件根据动态数据渲染另一个角度组件。我认为这需要内容投影,但我只能在简单的情况下使内容投影工作。

示例场景

我在 vanilla TypeScript 中有以下表格数据:

const headings = [
  { id: 'cat', label: 'Cat' },
  { id: 'nameIt', label: 'Type the name' }
]

const data = [
  { cat: 'Tabby', nameIt: (name) => updateTabbysName(name) },
  { cat: 'Ginger', nameIt: (name) => updateGingersName(name) },
]

我还有四个 Angular 组件:

  • simple-span 在范围内呈现文本。在这种情况下,它将渲染 cat 字段。
  • text-input 呈现文本输入。在这种情况下,它将呈现一个基本的 HTML 输入,当用户输入文本时将调用 nameIt 回调。
  • my-special-cat-table 将提供 headingsdata 变量,允许了解 text-inputsimple-span
  • generic-table 负责渲染表格 DOM 元素。 不允许知道text-inputsimple-span存在。

目的是让generic-table 完全看不到单元格渲染组件

是否有可能在 Angular 7 中实现这一点?

【问题讨论】:

  • 简短答案是否定的。
  • 目前,没有 100% 通用的解决方案。
  • 我认为您正在要求 ngx-datatableAngular Material Data Table 已经在做的事情。
  • 对于任何对我的去向感兴趣的人......我们最终切换到了 React。根本区别在于,React 是贯穿整个组件树的 JavaScript,而 Angular 在每个组件之间都有一个模板语言层。这意味着将未知/动态组件向下传递树是 React 是微不足道的,而在 Angular 中它目前是不可能的。或者至少不是通用的方式。

标签: javascript angular typescript


【解决方案1】:

您可以评估使用 NgTemplateOutlet 创建可重用组件。只是一个建议。

Take a look at this example.

【讨论】:

    【解决方案2】:

    声明性动态组件有*ngComponentOutlet 指令: https://angular.io/api/common/NgComponentOutlet

    请记住,您需要将它们全部放在entryComponents 中,以便 Injector 了解它们及其工厂。如果您发布更多代码,我们可以尝试找出确切的解决方案。

    基本上,它所做的是解析一个工厂,然后使用注入器创建它并添加到视图中:

        const componentFactory = this.componentFactoryResolver
            .resolveComponentFactory(component);
    
        this.componentRef = this.viewContainerRef.createComponent(componentFactory);
    

    您可以使用类似的想法编写自己的抽象,并让它与您想要的任何组件一起使用。奇怪这里的人说现在不可能了。

    【讨论】:

      【解决方案3】:

      您想要完成的是在循环中使用内容投影。这是 Angular 材质的示例:

      …
      <ng-container *ngFor=”let column of displayedColumns” matColumnDef=”{{column.id}}”>
         <th mat-header-cell *matHeaderCellDef mat-sort-header>{{column.name}}</th>
         <td mat-cell *matCellDef=”let row”>
            {{row[column.id]}}
         </td>
      </ng-container>
      …
      

      从使用代码可以看出,您可以创建多个模板并以任何您想要的方式组合它们:

      <my-component …
      [itemTemplate]=”itemTemplate”>
         <ng-template let-item #itemTemplate>
            column id: {{item.column.id}}
            value: {{item.value}}
         </ng-template>
      </my-component>
      

      source

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-30
        • 2020-03-21
        • 2019-06-03
        • 2019-09-23
        • 2019-03-23
        • 2019-02-23
        • 2019-08-24
        • 2018-08-06
        相关资源
        最近更新 更多