【问题标题】:*ngIf else if in template*ngIf else if 在模板中
【发布时间】:2017-10-04 09:32:15
【问题描述】:

*ngIf 语句中如何处理多个案例?我习惯 Vue 或 Angular 1 有一个 ifelse ifelse,但似乎 Angular 4 只有一个 true (if) 和 false (else ) 条件。

根据文档,我只能这样做:

<ng-container *ngIf="foo === 1; then first else second"></ng-container>
<ng-template #first>First</ng-template>
<ng-template #second>Second</ng-template>
<ng-template #third>Third</ng-template>

但我想有多个条件(类似):

<ng-container *ngIf="foo === 1; then first; foo === 2; then second else third"></ng-container>
<ng-template #first>First</ng-template>
<ng-template #second>Second</ng-template>
<ng-template #third>Third</ng-template>

但我最终不得不使用ngSwitch,这感觉就像一个黑客:

<ng-container [ngSwitch]="true">
  <div *ngSwitchCase="foo === 1">First</div>
  <div *ngSwitchCase="bar === 2">Second</div>
  <div *ngSwitchDefault>Third</div>
</ng-container>

另外,我在 Angular 1 和 Vue 中习惯的很多语法似乎在 Angular 4 中不受支持,那么推荐使用什么方法来构建具有此类条件的代码?

【问题讨论】:

  • 我认为你 hack 是最好的解决方案,因为它最具可读性。但是我已经意识到角度 switch 语句允许匹配多个条件,所以你不会得到真正的 elseif 逻辑。

标签: angular templates angular-ng-if


【解决方案1】:

另一种选择是嵌套条件

<ng-container *ngIf="foo === 1;else second"></ng-container>
<ng-template #second>
    <ng-container *ngIf="foo === 2;else third"></ng-container>
</ng-template>
<ng-template #third></ng-template>

【讨论】:

  • 这对我来说是更好的解决方案。我的条件基于多个变量,并且多个变量能够同时为真。
  • 我们不能像&lt;ng-template #second *ngIf="foo === 2;else third"&gt;那样使用
  • 在链接 ngIf 时,由前面的 else 寻址的 不支持另一个 ngIf。嵌套的 标签允许插入下一个条件。
【解决方案2】:

你可以使用:

<ng-template [ngIf]="index == 1">First</ng-template>
<ng-template [ngIf]="index == 2">Second</ng-template>
<ng-template [ngIf]="index == 3">Third</ng-template>

除非 ng-container 部分对我的设计很重要。

这是Plunker

【讨论】:

  • 我的例子有点简单,但期待“else if”行为,例如 if (index === 1) else if (foo === 2) 必须写成 if (index === 1) if (index !== 1 &amp;&amp; foo === 2) 有点混乱,更容易出错,越有时我们必须编写逆逻辑。
  • 你有没有看过plunker?我认为我没有看到这个问题,索引一次只会是一件事。
  • 我认为是我的例子缺乏解释,这里是 JS 中的一个例子:if (item === 'food' &amp;&amp; kind === 'hamburger') {} else if (item === 'food' &amp;&amp; kind === 'hotdog') {} else if (item === 'drink' &amp;&amp; kind === 'beer') {} else if (item === 'drink' &amp;&amp; kind === 'wine') {} else { /* could be poisonous */ }
  • 在那个例子中仍然有太多的互斥,但重点是,我需要做 if、else if 和 else,而不仅仅是 if 和 else,而不需要编写大量冗余逻辑。 Angular 4 的模板似乎缺少这种逻辑。
  • 还有其他一些选项,听起来您可能会受益于带有 *ngTemplateOutlet="drink; context: beer" 等上下文的NgTemplateOutlet,或者可能是另一个用于分类的组件。
【解决方案3】:

这似乎是最干净的方法

if (foo === 1) {

} else if (bar === 99) {

} else if (foo === 2) {

} else {

}

在模板中:

<ng-container *ngIf="foo === 1; else elseif1">foo === 1</ng-container>
<ng-template #elseif1>
    <ng-container *ngIf="bar === 99; else elseif2">bar === 99</ng-container>
</ng-template>
<ng-template #elseif2>
    <ng-container *ngIf="foo === 2; else else1">foo === 2</ng-container>
</ng-template>
<ng-template #else1>else</ng-template>

请注意,当条件涉及不同的变量(一次只有一种情况为真)时,它就像正确的else if 语句一样工作。在这种情况下,其他一些答案不起作用。

除了:gosh angular,那是一些非常丑陋的else if 模板代码...

【讨论】:

    【解决方案4】:

    您可以根据情况使用多种方式:

    1. 如果您的变量仅限于特定的 NumberString,最好的方法是使用 ngSwitch 或 ngIf:

      <!-- foo = 3 -->
      <div [ngSwitch]="foo">
          <div *ngSwitchCase="1">First Number</div>
          <div *ngSwitchCase="2">Second Number</div>
          <div *ngSwitchCase="3">Third Number</div>
          <div *ngSwitchDefault>Other Number</div>
      </div>
      
      <!-- foo = 3 -->
      <ng-template [ngIf]="foo === 1">First Number</ng-template>
      <ng-template [ngIf]="foo === 2">Second Number</ng-template>
      <ng-template [ngIf]="foo === 3">Third Number</ng-template>
      
      
      <!-- foo = 'David' -->
      <div [ngSwitch]="foo">
          <div *ngSwitchCase="'Daniel'">Daniel String</div>
          <div *ngSwitchCase="'David'">David String</div>
          <div *ngSwitchCase="'Alex'">Alex String</div>
          <div *ngSwitchDefault>Other String</div>
      </div>
      
      <!-- foo = 'David' -->
      <ng-template [ngIf]="foo === 'Alex'">Alex String</ng-template>
      <ng-template [ngIf]="foo === 'David'">David String</ng-template>
      <ng-template [ngIf]="foo === 'Daniel'">Daniel String</ng-template>
      
    2. 以上不适合if elseif else代码和动态代码,可以使用以下代码:

      <!-- foo = 5 -->
      <ng-container *ngIf="foo >= 1 && foo <= 3; then t13"></ng-container>
      <ng-container *ngIf="foo >= 4 && foo <= 6; then t46"></ng-container>
      <ng-container *ngIf="foo >= 7; then t7"></ng-container>
      
      <!-- If Statement -->
      <ng-template #t13>
          Template for foo between 1 and 3
      </ng-template>
      <!-- If Else Statement -->
      <ng-template #t46>
          Template for foo between 4 and 6
      </ng-template>
      <!-- Else Statement -->
      <ng-template #t7>
          Template for foo greater than 7
      </ng-template>
      

    注意:您可以选择任何格式,但请注意每个代码都有自己的问题

    【讨论】:

    • IMO 2. 应阅读 *ngIf="foo &gt;= 7; then t7" 而不是 ... else t7
    • 我认为只有两行,第二行是foo &gt;= 4 &amp;&amp; foo &lt;= 6; then t46; else t7 应该可以工作。
    【解决方案5】:

    为了避免嵌套和ngSwitch,也有这种可能性,它利用了逻辑运算符在Javascript中的工作方式:

    <ng-container *ngIf="foo === 1; then first; else (foo === 2 && second) || (foo === 3 && third)"></ng-container>
      <ng-template #first>First</ng-template>
      <ng-template #second>Second</ng-template>
      <ng-template #third>Third</ng-template>
    

    【讨论】:

      【解决方案6】:

      或者也许只是使用带有三元运算符的条件链。 if … else if … else if … else链。

      https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator#Conditional_chains

      <ng-container [ngTemplateOutlet]="isFirst ? first : isSecond ? second : third"></ng-container>
      
      <ng-template #first></ng-template>
      <ng-template #second></ng-template>
      <ng-template #third></ng-template>
      

      我更喜欢这种方法。

      【讨论】:

        【解决方案7】:

        如果使用 ng-container,则不需要使用 *ngIf

        <ng-container [ngTemplateOutlet]="myTemplate === 'first' ? first : myTemplate === 
           'second' ? second : third"></ng-container>
        
          <ng-template #first>first</ng-template>
          <ng-template #second>second</ng-template>
          <ng-template #third>third</ng-template>
        

        【讨论】:

          【解决方案8】:

          <ion-row *ngIf="cat === 1;else second"></ion-row>
          <ng-template #second>
              <ion-row *ngIf="cat === 2;else third"></ion-row>
          </ng-template>
          <ng-template #third>
          
          </ng-template>

          Angular 已经在很多应用中使用了 ng-template 我们一直使用的结构指令:ngIf、ngFor 和 ngSwitch。

          > Angular 中的 ng-template 是什么

          https://www.angularjswiki.com/angular/what-is-ng-template-in-angular/

          【讨论】:

            【解决方案9】:

            我遇到了*ngIf elseIf else这种情况,我用ng-template解决了,希望下面的sn-p可以简要描述一下,

            我有一个名为“NIC”的表单控件,当表单控件无效时,我需要一次显示一条错误消息。

            form: FormGroup = new FormGroup({
                NIC: new FormControl('', [Validators.required, Validators.minLength(10), Validators.maxLength(10), Validators.pattern("^[0-9]*$")])
              });
            

            模板

            <mat-form-field appearance="standard">
                <mat-label>NIC Number</mat-label>
                <input matInput placeholder="Enter NIC no" formControlName="NIC">
                <mat-error *ngIf="form.controls['NIC'].errors?.required; else minvalue">This field is mandatory.
                </mat-error>
            
                <ng-template #minvalue>
                    <mat-error *ngIf="form.controls['NIC'].errors?.minlength; else maxvalue">Minimum 10 charactors
                        needed.
                    </mat-error>
                </ng-template>
            
                <ng-template #maxvalue>
                    <mat-error *ngIf="form.controls['NIC'].errors?.maxLength; else numericonly">Maximum 10
                        charactors allowed.
                    </mat-error>
                </ng-template>
            
                <ng-template #numericonly>
                    <mat-error *ngIf="form.controls['NIC'].errors?.pattern">
                        Numeric characters only.
                    </mat-error>
                </ng-template>
            
            </mat-form-field>
            

            【讨论】:

              【解决方案10】:

              您还可以使用这个老技巧将复杂的 if/then/else 块转换为更简洁的 switch 语句:

              <div [ngSwitch]="true">
                  <button (click)="foo=(++foo%3)+1">Switch!</button>
              
                  <div *ngSwitchCase="foo === 1">one</div>
                  <div *ngSwitchCase="foo === 2">two</div>
                  <div *ngSwitchCase="foo === 3">three</div>
              </div>
              

              【讨论】:

              • *ngSwitchDefault 指令将提供“其他”情况。
              • 这种方法是 OP 在他们的问题中提到的一种方法,并表示他们不喜欢。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2010-09-22
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-10-04
              • 2011-06-26
              • 1970-01-01
              相关资源
              最近更新 更多