Angular在没有复制/粘贴代码的情况下渲染一个或另一个模板

时间:2018-10-04 17:30:55

标签: css angular html5 angular-material angular-ng-if

问题的工作原理如下。 我有一些实际上是这样的代码:

<content1>
    <mat-horizontal-stepper *ngIf="somevar" >
        <content2></content2>
    </mat-horizontal-stepper>
    <mat-vertical-stepper *ngIf="!somevar" >
    <content2></content2>
    </mat-vertical-stepper>
</content1>

我的意思是,content2始终相同,但是垫步进器是垂直或水平的 如果somevar是对还是错

如何在不复制content2的代码的情况下实现这一目标?

Posdata:我无法创建另一个组件来容纳content2的内容,因为我需要在步进器中的content1中使用的变量,而且我绝对不想复制/粘贴代码。我将如何根据somevar呈现内容只是一回事。

2 个答案:

答案 0 :(得分:5)

通常,如果您不能使用组件,则可以使用模板和容器多次显示相同的内容。

在下面的示例中,我将container-2元素替换为ng-container组件。在其他地方,我添加了ng-template组件并将container-2放入内容中。最后,我通过将*ngTemplateOutlet指令放在容器上,并使用模板变量将对它们的引用传递给模板,来将两者关联起来。

<content1>
  <mat-horizontal-stepper *ngIf="somevar" >
    <ng-container *ngTemplateOutlet="content2Template"></ng-container>
  </mat-horizontal-stepper>
  <mat-vertical-stepper *ngIf="!somevar" >
    <ng-container *ngTemplateOutlet="content2Template"></ng-container>
  </mat-vertical-stepper>
</content1>
<ng-template #content2Template>
  <content2></content2>
</ng-template>

但是,如果您使用角形材料“步进器”和“台阶”,则此方法将无效。原因是因为Step组件期望将祖先Stepper组件注入到其中。由于您想重用模板,因此模板必须超出步进器的尺寸,因此您无法满足进样要求。上面的方法在子组件希望父组件被注入的任何情况下都不起作用。

唯一的其他解决方案是对内容本身使用模板。因此,当重复步骤组件时,它们内部的形式将不会重复。大概形式就是内容的实质,因此不会有太多重复。

<mat-vertical-stepper> *ngIf="somevar" 
  <mat-step label="Step 1" >
    <ng-container *ngTemplateOutlet="Content1"></ng-container>
  </mat-step>
  <mat-step label="Step 2">
    <ng-container *ngTemplateOutlet="Content2"></ng-container>
  </mat-step>
</mat-vertical-stepper>
<mat-horizontal-stepper>
  <ng-template #tmplt let-stepper *ngIf="!somevar">
    <mat-step label="Step 1" >
      <ng-container *ngTemplateOutlet="Content1"></ng-container>
    </mat-step>
    <mat-step label="Step 2">
      <ng-container *ngTemplateOutlet="Content2"></ng-container>
    </mat-step>
  </ng-template>    
  <ng-container *ngTemplateOutlet="tmplt"></ng-container>
</mat-horizontal-stepper>
<ng-template #Content1>Content1</ng-template>
<ng-template #Content2>Content2</ng-template>

答案 1 :(得分:0)

您还可以为步进器编写一个新的包装器组件,该组件然后在属性上分支(无论是垂直还是水平)。

<mat-stepper [orientation]="somevar ? 'horizontal' : 'vertical'">
  <content2></content2>
</mat-stepper>

垫子步进看起来像

<ng-container *ngIf="orientation === 'horizontal'; else vertical">
  <mat-horizontal-stepper>
    <ng-content>
  </mat-horizontal-stepper>
</ng-container>
<ng-template #vertical>
  <mat-vertical-stepper>
    <ng-content>
  </mat-vertical-stepper>
</ng-template>

如果您多次在代码中遇到此问题,这是一个很好的解决方案