如何动态实现包含1-N个其他组件的可重用角度组件?

时间:2019-04-05 11:10:37

标签: angular

如何做到这一点,以使容器组件不了解其包含的组件?

我正在尝试开发一种可以包含任何内容的通用侧面板控件。每个组件在顶部和下方的选择器行中均由图标表示,它们是垂直放置的组件。单击图标可滚动容器,以便可见相应的组件。

静态示例,其中不同项目位于同一html中:

  <mat-sidenav opened mode="side" position="end">
   <div class="sidewindow">
    <div class="header">
      <button  mat-icon-button (click)="scroll(properties)">
          <mat-icon>settings</mat-icon>
      </button>
      <button  mat-icon-button (click)="scroll(table)">
          <mat-icon>table_chart</mat-icon>
      </button>
      <button  mat-icon-button (click)="scroll(maintenance)">
          <mat-icon>gavel</mat-icon>
      </button>
    </div>
    <div class="content">
      <div #properties>
        <mat-card >
            <mat-card-title>Properties</mat-card-title>
              <form class="example-form">
                <mat-form-field class="example-full-width">
                  <input matInput placeholder="Favorite food" value="Sushi">
                </mat-form-field>

                <mat-form-field class="example-full-width">
                  <textarea matInput placeholder="Leave a comment"></textarea>
                </mat-form-field>
              </form>
            </mat-card>
      </div>
      <div  #table>
        <mat-card>
            <mat-card-title>Table</mat-card-title>
        <table mat-table [dataSource]="dataSource">
            <!-- Position Column -->
            <ng-container matColumnDef="position">
              <th mat-header-cell *matHeaderCellDef> No. </th>
              <td mat-cell *matCellDef="let element"> {{element.position}} </td>
            </ng-container>

            <!-- Name Column -->
            <ng-container matColumnDef="name">
              <th mat-header-cell *matHeaderCellDef> Name </th>
              <td mat-cell *matCellDef="let element"> {{element.name}} </td>
            </ng-container>

            <!-- Weight Column -->
            <ng-container matColumnDef="weight">
              <th mat-header-cell *matHeaderCellDef> Weight </th>
              <td mat-cell *matCellDef="let element"> {{element.weight}} </td>
            </ng-container>

            <!-- Symbol Column -->
            <ng-container matColumnDef="symbol">
              <th mat-header-cell *matHeaderCellDef> Symbol </th>
              <td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
            </ng-container>

            <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
            <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
          </table>
        </mat-card>
      </div>
      <div #maintenance>
          <mat-card>
              <mat-card-title>Maintenance</mat-card-title>
              <mat-card-subtitle>Subtitle</mat-card-subtitle>
              <p>The actual content</p>
              <p>The actual content 2</p>
              <p>The actual content 3</p>

          </mat-card>
      </div>
    </div>
  </div>
</mat-sidenav>

2 个答案:

答案 0 :(得分:1)

根据您的需要有多种方法:

  1. 使用ng-content,可以将子组件投影到侧面板组件中。 https://blog.angular-university.io/angular-ng-content/
  2. 您可以使用NgComponentOutlet将组件动态添加到侧面板模板中,并带有控件以注入自定义数据。 https://angular.io/api/common/NgComponentOutlet#description
  3. 使用ComponentFactoryResolver可以动态实例化组件。 https://angular.io/guide/dynamic-component-loader#dynamic-component-loader
  

注意:#2和#3要求将组件注册到   entryComponents数组供Angular在编译时了解它们   时间。

答案 1 :(得分:0)

我认为您正在寻找的是带有ng-content的多时隙插入。例如,您可以查看Todd Motto's tutorial,以了解如何在Angular中执行此操作。您必须进行调整才能拥有图标系统,但是通过这种方式,您可以在面板中包含所需的任何组件。您的html可能如下所示:

<side-panel-component>
    <my-comp1></my-comp1>
    <my-comp2></my-comp2>
    <div class>...</div>
    ...
</side-panel-component>

我从没做过这样的事情,但是我经常使用包含,我想我会尝试一下。