* ngIf else if in template


109

ฉันจะมีหลายกรณีใน*ngIfแถลงการณ์ได้อย่างไร? ฉันใช้ Vue หรือเชิงมุม 1 มีif, else ifและelseแต่มันดูเหมือนว่าเชิงมุม 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 ดังนั้นวิธีที่แนะนำในการจัดโครงสร้างโค้ดของฉันด้วยเงื่อนไขเช่นนี้จะเป็นอย่างไร


ฉันคิดว่าคุณแฮ็คเป็นทางออกที่ดีที่สุดเพราะอ่านได้มากที่สุด อย่างไรก็ตามฉันได้ตระหนักว่าคำสั่งสวิตช์เชิงมุมอนุญาตให้มีหลายเกณฑ์ที่จะจับคู่ดังนั้นคุณจะไม่ได้ตรรกะอื่นที่แท้จริงนั้น
Tom Benyon

คำตอบ:


155

อีกทางเลือกหนึ่งคือเงื่อนไขรัง

<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>

4
นี่เป็นทางออกที่ดีกว่าสำหรับฉัน เงื่อนไขของฉันขึ้นอยู่กับตัวแปรหลายตัวและมีมากกว่าหนึ่งตัวที่สามารถเป็นจริงได้ในเวลาเดียวกัน
Matt DeKok

1
เราใช้ไม่ได้เช่น<ng-template #second *ngIf="foo === 2;else third">
Loki

เมื่อเชื่อมโยง ngIf <ng-template> ซึ่งถูกระบุโดยสิ่งอื่นก่อนหน้านี้จะไม่รองรับ ngIf อื่น แท็ก <ng-container> ที่ซ้อนกันอนุญาตให้แทรกเงื่อนไขถัดไป
Constantin Konstantinidis

36

คุณสามารถใช้:

<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


1
ตัวอย่างของฉันค่อนข้างง่าย แต่คาดหวังว่าพฤติกรรม 'else if' if (index === 1) else if (foo === 2)ซึ่งจะต้องถูกเขียนif (index === 1) if (index !== 1 && foo === 2)ซึ่งค่อนข้างยุ่งและมีแนวโน้มที่จะเกิดข้อผิดพลาดยิ่งเราต้องเขียนตรรกะผกผันหลายครั้ง

คุณได้ดูคนบ้า? ฉันไม่คิดว่าฉันจะเห็นปัญหานี้ดัชนีจะเป็นเพียง 1 รายการในแต่ละครั้ง
Dylan

ฉันคิดว่ามันเป็นตัวอย่างของฉันที่ไม่มีคำอธิบายนี่คือตัวอย่างใน JS: if (item === 'food' && kind === 'hamburger') {} else if (item === 'food' && kind === 'hotdog') {} else if (item === 'drink' && kind === 'beer') {} else if (item === 'drink' && kind === 'wine') {} else { /* could be poisonous */ }

1
ยังคงมีการยกเว้นซึ่งกันและกันมากเกินไปในตัวอย่างนั้น แต่ถึงกระนั้นประเด็นก็คือฉันต้องทำ if, else if, and else ไม่ใช่แค่ if และ else โดยไม่ต้องเขียนตรรกะซ้ำซ้อนมากมาย ดูเหมือนว่าเทมเพลตของ Angular 4 จะขาดตรรกะแบบนี้

1
มีตัวเลือกอื่น ๆ อีกเล็กน้อยซึ่งดูเหมือนว่าคุณอาจได้รับประโยชน์จาก NgTemplateOutletบริบทเช่น * ngTemplateOutlet = "drink; context: beer" หรืออาจเป็นส่วนประกอบอื่นสำหรับการจัดหมวดหมู่
Dylan

26

นี่ดูเหมือนจะเป็นวิธีที่สะอาดที่สุด

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คำสั่งที่เหมาะสมเมื่อเงื่อนไขเกี่ยวข้องกับตัวแปรที่แตกต่างกัน (มีเพียง 1 กรณีเท่านั้นที่เป็นจริงในแต่ละครั้ง) คำตอบอื่น ๆ บางคำตอบไม่ได้ผลในกรณีเช่นนี้

กัน: เอ้ยเชิงมุมนั่นคือelse ifรหัสเทมเพลตที่น่าเกลียดจริงๆ...


18

คุณสามารถใช้ได้หลายวิธีตามข้อควรระวัง:

  1. หากตัวแปรของคุณถูก จำกัด เฉพาะNumberหรือStringวิธีที่ดีที่สุดคือใช้ 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รหัสอื่นและรหัสไดนามิกคุณสามารถใช้รหัสด้านล่าง:

    <!-- 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>
    

หมายเหตุ: คุณสามารถเลือกรูปแบบใดก็ได้ แต่สังเกตว่าทุกรหัสมีปัญหาในตัวเอง


1
IMO 2. ควรอ่าน*ngIf="foo >= 7; then t7"แทน... else t7.
hgoebl

ฉันคิดว่าแค่สองบรรทัดกับบรรทัดที่สองfoo >= 4 && foo <= 6; then t46; else t7ก็น่าจะใช้ได้
Cloud

9

เพื่อหลีกเลี่ยงการซ้อนและ 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 *ngIf="isFirst ? first: isSecond ? second : third"></ng-container>

<ng-template #first></ng-template>
<ng-template #second></ng-template>
<ng-template #third></ng-template>

ฉันชอบ aproach นี้ดีกว่า


0

<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

> ng-template ใน Angular คืออะไร

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


0

คุณยังสามารถใช้เคล็ดลับเก่านี้ในการแปลงคอมเพล็กซ์ถ้า / แล้ว / else บล็อกเป็นคำสั่งสวิตช์ที่สะอาดกว่าเล็กน้อย:

<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>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.