ใช้คำสั่งตามเงื่อนไข


112

ฉันใช้วัสดุที่ 2 md-raised-buttonการเพิ่ม ฉันต้องการใช้คำสั่งนี้ก็ต่อเมื่อเงื่อนไขบางอย่างกลายเป็นจริง

ตัวอย่างเช่น:

<button md-raised-button="true"></button>

อีกตัวอย่างหนึ่ง: ฉันสร้างรูปแบบปฏิกิริยาไดนามิกพื้นฐานใน plunker ฉันใช้formArrayNameคำสั่งของรูปแบบปฏิกิริยาสำหรับอาร์เรย์ของการควบคุม ฉันต้องการใช้formArrayNameคำสั่งเฉพาะในกรณีที่เงื่อนไขเฉพาะกลายเป็นจริงมิฉะนั้นอย่าเพิ่มformArrayNameคำสั่ง

นี่คือการเชื่อมโยง plunker


ใช่ปุ่มยก md เป็นคำสั่งแอตทริบิวต์ ( material.angular.io/components/component/button )
user2899728

การใช้เงื่อนไขในการใช้คำสั่งอาจทำให้ AoT ไร้ประโยชน์เนื่องจากคุณจะไม่สามารถรวบรวมเทมเพลตได้เว้นแต่แอปจะทำงานอยู่
Reactgular

คำตอบ:


55

ผมไม่ทราบว่าคุณสามารถใช้คำสั่งขึ้นอยู่กับสภาพ แต่การแก้ปัญหาจะมี2 ปุ่มและแสดงให้พวกเขาขึ้นอยู่กับเงื่อนไข

<button *ngIf="!condition"></button>
<button *ngIf="condition" md-raised-button></button> 

แก้ไข: บางทีนี่อาจเป็นประโยชน์


13
ขอขอบคุณสำหรับการตอบสนองของคุณ. แต่ฉันได้ใช้เทคนิคนี้ในตัวอย่าง plunker แล้วซึ่งฉันได้เพิ่มในรายละเอียดคำถาม นี่เป็นตัวเลือกที่ดี แต่ไม่ใช่ความคิดที่ดีหากโค้ดมีความซับซ้อน เพราะเนื่องจากเทคนิคนี้ทำลายแนวคิดการนำกลับมาใช้ใหม่ คุณสามารถดูตัวอย่างของฉันได้ใน plunker และสังเกตว่ารหัสของฉันซ้ำกันอย่างไรเนื่องจากวิธีนี้ นั่นคือเหตุผลที่ฉันไม่ต้องการใช้เทคนิคนี้ ฉันต้องการโซลูชันที่ดีกว่าเพื่อสร้างองค์ประกอบแบบไดนามิกด้วย.
user2899728

1
ฉันเห็น. คุณสามารถตัดโค้ดที่ซ้ำกันในคอมโพเนนต์
LLL

3
เป็นความคิดที่ดี แต่น่าเสียดายที่ใช้ไม่ได้ในกรณีของรูปแบบปฏิกิริยา ด้วยรูปแบบที่ตอบสนองปัญหาอื่นจะปรากฏขึ้น ถ้าฉันใส่ข้อมูลลงในองค์ประกอบแยกจากนั้นเชิงมุมก็ต้องการให้ฉันเพิ่ม [formGroup] = "form" ภายในองค์ประกอบลูกนั้นด้วย แต่ถ้าฉันทำเช่นนั้นการผูกอาร์เรย์ของฉันจะไม่ทำงาน
user2899728

15
นั่นเป็นวิธีแก้ปัญหาที่ยอดเยี่ยมเนื่องจากเป็นรหัสที่ซ้ำกัน ลองนึกภาพว่ามันไม่ใช่แค่ปุ่ม แต่เป็น div ที่มีโค้ด html อยู่ข้างใน
Shachar Har-Shuv

ไม่จำเป็นต้องรวมformGroupไว้ในส่วนประกอบย่อยที่ห่อหุ้มinputเนื่องจากคุณสามารถส่งผ่านของคุณformControlเป็นส่วนประกอบ@Input() control: FormControlภายในกระดาษห่อหุ้มและนำไปใช้กับเนทีฟได้inputทาง[formControl]="control"
Oleg Kuibar

88

หากคุณต้องการเพิ่มแอตทริบิวต์เพื่อเรียกใช้กฎ CSS คุณสามารถใช้วิธีการด้านล่าง: (สิ่งนี้ไม่ได้สร้าง / ทำลายคำสั่งแบบไดนามิก)

<button [attr.md-raised-button]="condition ? '' : null"></button>

นำไปใช้กับคนขับรถของคุณ: ส้อม

อัปเดต:

วิธีการcondition ? '' : nullทำงานเป็นค่า:

เมื่อสตริงว่าง ( '') กลายเป็นattr.md-raised-button=""เมื่อnullนั้นแอตทริบิวต์จะไม่มีอยู่

อัปเดต: การอัปเดต plunker: fork (แก้ไขปัญหาเวอร์ชันโปรดทราบว่าคำถามเดิมขึ้นอยู่กับเชิงมุม 4)


@ ลุคใช่ถ้าคุณหมายถึง"(ตอนนี้)"เป็น: ตั้งแต่ 2017-01-06 ซึ่งเป็นเวลา 5 เดือนก่อนที่คำถามจะถูกถาม ดูบันทึกการเปลี่ยนแปลงเชิงมุมรายการที่ 6
Aldracor

@Aldracor angular 5.2.1 ไม่ทำงาน และฉันไม่เข้าใจว่าเหตุใดจึงควรมีลักษณะเป็น "condition? '': null" โดยที่ผลลัพธ์ทั้งสองเป็นเท็จ ควรเป็นอะไรแทน ''? 'true' ก็ใช้ไม่ได้เช่นกัน
Arsenii Fomin

1
ดังนั้นสำหรับใครก็ตามที่ไม่ต้องการสร้างองค์ประกอบ html เพื่อให้คำสั่งของพวกเขาทำงานและกำลังใช้ ng-container ฉันเพิ่งไปด้วยการส่ง [เปิดใช้งาน] = "booleanVar"
Ben Taliadoros

7
ไม่ได้ผลสำหรับฉันใน Angular 6 ตัวอย่าง plunker ไม่ผ่านหน้าจอโหลด จากการอ่านของฉันวิธีนี้อาจใช้ได้กับแอตทริบิวต์ HTML แต่จะใช้ไม่ได้กับคำสั่ง Angular คำถามเดิมเกี่ยวกับ Angular Directives จากคลังวัสดุ ng
JeffryHouser

6
@kbpontius ขอบคุณสำหรับความคิดเห็นมันใช้งานได้กับแอตทริบิวต์ Html แต่ไม่ใช่ในคำสั่งเชิงมุม (เป็นแอตทริบิวต์)
Reza

19

ตามที่ระบุไว้แล้วสิ่งนี้ดูเหมือนจะเป็นไปไม่ได้ ng-templateสิ่งหนึ่งที่สามารถนำมาใช้อย่างน้อยป้องกันการทำสำเนาบางส่วน สิ่งนี้ช่วยให้คุณแยกเนื้อหาขององค์ประกอบที่ได้รับผลกระทบจากการngIfแตกแขนง

ตัวอย่างเช่นหากคุณต้องการสร้างส่วนประกอบเมนูแบบลำดับชั้นโดยใช้ Angular Material:

<!-- Button contents -->
<ng-template #contentTemplate>
    <mat-icon *ngIf="item.icon != null">{{ item.icon }}</mat-icon>
    {{ item.label }}
</ng-template>

<!-- Leaf button -->
<button *ngIf="item.children == null" mat-menu-item
    (click)="executeCommand()"
    [disabled]="enabled == false">
    <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
</button>
<!-- Node button -->
<ng-container *ngIf="item.children != null">
    <button mat-menu-item
        [matMenuTriggerFor]="subMenu">
        <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
    </button>

    <mat-menu #subMenu="matMenu">
        <menu-item *ngFor="let child of item.children" [item]="child"></menu-item>
    </mat-menu>
</ng-container>

นี่คือคำสั่งที่ใช้ตามเงื่อนไขmatMenuTriggerForซึ่งควรใช้กับรายการเมนูที่มีเด็กเท่านั้น ngTemplateOutletเนื้อหาของปุ่มจะแทรกอยู่ในสถานที่ทั้งสองทาง


6
นี่เป็นคำตอบเดียวที่ให้นักพัฒนาใช้คำสั่งแบบมีเงื่อนไขรวมถึงการใช้งานโค้ดซ้ำได้
Ravinder Payal

16

สิ่งนี้อาจมาช้า แต่เป็นวิธีการที่ใช้ได้ผลและสวยงามในการใช้คำสั่งตามเงื่อนไข

ในคลาสคำสั่งให้สร้างตัวแปรอินพุต:

@Input('myDirective') options: any;

เมื่อใช้คำสั่งตั้งค่าคุณสมบัติใช้ของตัวแปรอินพุต:

<div [myDirective] = {apply: someCondition}></div>

ในวิธีการตรวจสอบคำสั่งสำหรับตัวแปร this.options.apply และใช้ตรรกะคำสั่งตามเงื่อนไข:

ngAfterViewInit(): void {
    if (!this.options.apply) {
        return;
    }

    // directive logic
}

3
สิ่งนี้ไม่ได้ผลสำหรับฉันเนื่องจากคำสั่งยังคงมีอยู่ในส่วนประกอบจึงไม่ใช้ตรรกะ ฉันต้องการให้การดำรงอยู่ของคำสั่งเป็นไปตามเงื่อนไขโดยเฉพาะเนื่องจากมี css ที่ตรวจสอบคำสั่งนี้
Ran Lottem

คุณมีปัญหาที่แตกต่างจากที่ระบุไว้ที่นี่ (ใช้คำสั่งตามเงื่อนไข) โพสต์ปัญหาของคุณแล้วคนอื่นจะช่วยคุณ ตามแนวคิดแรกคุณสามารถวางคำสั่งลงบน div และวาง ng-container ที่มี * ngIf ล้อมรอบเพื่อใช้เงื่อนไข ngIf ลบโหนด div ออกจาก DOM ดังนั้นจึงอาจใช้งานได้ ฉันแค่คาดเดาคุณต้องโพสต์ปัญหาของคุณพร้อมตัวอย่างรหัส / คำอธิบายสำหรับ ppl เพื่อช่วยคุณ
Tiha

นี่ไม่ใช่ทางออกที่ดี คำสั่งยังคงได้รับการเริ่มต้น
Dino

8

ตามที่คนอื่นระบุไว้เช่นกันdirectivesไม่สามารถใช้แบบไดนามิกได้

แต่ถ้าคุณเพียงต้องการที่จะสลับmd-button'สไตล์จากแบนที่จะยกขึ้นแล้วนี้

<button md-button [class.mat-raised-button]="isRaised">Toggle Raised Button</button>

จะทำเคล็ดลับ Plunker


3

นี่อาจเป็นวิธีแก้ปัญหาเช่นกัน:

[md-raised-button]="condition ? 'true' : ''"


มันทำงานสำหรับเชิงมุม 4, ไอออนิก 3 เช่นนี้:

[color]="condition ? 'primary' : ''"ซึ่งconditionเป็นฟังก์ชันที่ตัดสินว่านี่คือหน้าที่ใช้งานอยู่หรือไม่ รหัสทั้งหมดมีลักษณะดังนี้:

<button *ngFor="let page of ..." [color]="isActivePage(page) ? 'primary' : ''">{{ page.title }}</button>


2

ขณะนี้มีNOวิธีใช้คำสั่งแบบมีเงื่อนไขกับคอมโพเนนต์ซึ่งไม่รองรับคอมโพเนนต์ที่คุณสร้างขึ้นสามารถเพิ่มหรือลบออกได้ตามเงื่อนไข

มีปัญหาที่สร้างขึ้นสำหรับสิ่งเดียวกันอยู่angular2แล้วดังนั้นจึงควรเป็นกรณีที่มี angular4 เช่นกัน

หรือคุณสามารถไปที่ตัวเลือกด้วย ng-if

<button ngIf="!condition"></button>
<button ngIf="condition" md-raised-button></button> 


2

ฉันไม่พบวิธีแก้ปัญหาที่ดีที่มีอยู่ดังนั้นฉันจึงสร้างคำสั่งของตัวเองซึ่งทำสิ่งนี้

import { Directive, ElementRef, Input } from '@angular/core';

@Directive({
  selector: '[dynamic-attr]'
})
export class DynamicAttrDirective {
  @Input('dynamic-attr') attr: string;
  private _el: ElementRef;

  constructor(el: ElementRef) {
    this._el = el;
  }

  ngOnInit() {
    if (this.attr === '') return null;
    const node = document.createAttribute(this.attr);
    this._el.nativeElement.setAttributeNode(node);
  }
}

จากนั้น html ของคุณ:

<div dynamic-attr="{{hasMargin: 'margin-left' ? ''}}"></div>


คุณสามารถใช้เพียง a @HostBinding('attr.dynamic-attr') @Input('dynamic-attr') attr: string;แทน ngOnInit + ElementRef
pinguinjkeke

2
นี่ไม่ใช่คำตอบสำหรับคำถามซึ่งเป็นวิธีการเพิ่มคำสั่งแบบไดนามิกไม่ใช่แอตทริบิวต์
Chris Haines

2

บางทีมันอาจจะช่วยใครบางคน

ในตัวอย่างด้านล่างฉันมีmy-button.component.htmlและฉันต้องการใช้*appHasPermissionคำสั่งกับ<button>เฉพาะในกรณีที่roleมีการตั้งค่าแอตทริบิวต์

<ng-container *ngIf="role; else buttonNoRole" >
  <ng-container *appHasPermission="role">
    <!-- button with *appHasPermission -->
    <ng-template *ngTemplateOutlet="buttonNoRole;"></ng-template>
  </ng-container>
</ng-container>

<ng-template #buttonNoRole>
  <!-- button without *appHasPermission -->
  <button
    mat-raised-button type="button"
    [color]="color"
    [disabled]="disabled"
    [(appClickProgress)]="onClick"
    [key]="progressKey">
    <mat-icon *ngIf="icon">{{ icon }}</mat-icon> {{ label }}
  </button>
</ng-template>

ด้วยวิธีนี้คุณจะไม่ทำซ้ำ<button>รหัส


0

ใช่มันเป็นไปได้

หน้า html พร้อม appActiveAhover directive :)

  <li routerLinkActive="active" #link1="routerLinkActive">
        <a [appActiveAhover]='link1.isActive?false:true' routerLink="administration" [ngStyle]="{'background':link1.isActive?domaindata.get_color3():none}">
          <i class="fa fa-users fa-lg" aria-hidden="true"></i> Administration</a>
      </li>
      <li  routerLinkActive="active" #link2="routerLinkActive">
        <a [appActiveAhover]='link2.isActive?false:true' routerLink="verkaufsburo" [ngStyle]="{'background':link2.isActive?domaindata.get_color3():none,'color':link2.isActive?color2:none}">
          <i class="fa fa-truck fa-lg" aria-hidden="true"></i> Verkaufsbüro</a>
      </li>
      <li  routerLinkActive="active" #link3="routerLinkActive">
        <a [appActiveAhover]='link3.isActive?false:true' routerLink="preisrechner" [ngStyle]="{'background':link3.isActive?domaindata.get_color3():none}">
          <i class="fa fa-calculator fa-lg" aria-hidden="true" *ngIf="routerLinkActive"></i> Preisrechner</a>
      </li>

คำสั่ง

@Directive({
  selector: '[appActiveAhover]'
})
export class ActiveAhoverDirective implements OnInit {
  @Input() appActiveAhover:boolean;
  constructor(public el: ElementRef, public renderer: Renderer, public domaindata: DomainnameDataService) {
}

  ngOnInit() {
  }

  @HostListener('mouseover') onMouseOver() {
    if(this.appActiveAhover){
      this.renderer.setElementStyle(this.el.nativeElement, 'color', this.domaindata.domaindata.color2);
    }
  }

  @HostListener('mouseout') onMouseOut() {
    if(this.appActiveAhover){
      this.renderer.setElementStyle(this.el.nativeElement, 'color', 'white');
    }
  }

}

2
ในฐานะที่เป็นหมายเหตุด้านข้าง Renderer ถูกเลิกใช้งานแทนใช้ Renderer2: alligator.io/angular/using-renderer2
tam.teixeira


-1

ใช้ NgClass

[ngClass]="{ 'mat-raised-button': trueCondition }"

ตัวอย่างสภาพจริง:

this.element === 'Today'

หรือฟังก์ชันบูลีน

getTruth()

ตัวอย่างเต็ม:

  <button [ngClass]="{ 'mat-raised-button': trueCondition }">TEXT</button>

หากคุณต้องการคลาสเริ่มต้น:

  <button [ngClass]="{ 'mat-raised-button': trueCondition, 'default-class': !trueCondition }">TEXT</button>

6
นี่ไม่ใช่สิ่งที่ฉันถาม คุณกำลังแสดงตัวอย่างสำหรับชั้นเรียน ฉันกำลังพูดถึงแอตทริบิวต์ - คำสั่ง
user2899728

@ user2899728 น่าเสียดายที่ไม่มีวิธีอื่นให้ทำ (คุณไม่สามารถตั้งค่าmd-raised-buttonแอตทริบิวต์เป็นเท็จได้)
Edric

@ user2899728 ไม่มีวิธีใช้คำสั่งแบบมีเงื่อนไข ฉันพยายามให้สิ่งที่คุณกำลังมองหา (ผลลัพธ์สุดท้าย) ด้วยวิธีการที่แตกต่างออกไป ("หมายถึง")
Moshe

เมื่อคุณเสนอทางเลือกที่สร้างสรรค์โดยทั่วไปการใส่บรรทัดความคิดเห็นก่อนเพื่ออธิบายว่าคุณกำลังจะไปที่ใดพร้อมกับคำตอบของคุณ
bvdb

1
@bvdb ขอบคุณสำหรับคำพูดของคุณ ฉันเขียนโดยไร้ทิศทางและนั่นเป็นความผิดพลาด ในอนาคตฉันหวังว่าจะแก้ไขโพสต์นี้เพราะจะช่วยได้แม้แต่คนเดียว
Moshe

-1

ฉันมีความคิดอีกอย่างว่าคุณทำอะไรได้บ้าง

คุณสามารถเก็บ html ที่ที่คุณต้องการแทนที่ในตัวแปรเป็นสตริงและจากนั้นเพิ่ม / ลบคำสั่งจากมันตามที่คุณต้องการโดยใช้bypassSecurityTrustHtmlวิธีการDomSanitizer

ฉันไม่ได้ผลลัพธ์ในการแก้ปัญหาที่สะอาด แต่อย่างน้อยคุณก็ไม่จำเป็นต้องทำรหัสซ้ำ


-3

ณ วันที่ 18 มกราคม 2019 นี่คือวิธีที่ฉันเพิ่มคำสั่งแบบมีเงื่อนไขใน Angular 5 ขึ้นไป ฉันต้องการเปลี่ยนสีของ<app-nav>ส่วนประกอบตามdarkMode. หากหน้าอยู่ในโหมดมืดหรือไม่

สิ่งนี้ใช้ได้ผลสำหรับฉัน:

<app-nav [color]="darkMode ? 'orange':'green'"></app-nav>

ฉันหวังว่านี่จะช่วยใครบางคนได้

แก้ไข

สิ่งนี้จะเปลี่ยนค่าของแอตทริบิวต์ (สี) ตามเงื่อนไข มันเกิดขึ้นที่สีถูกกำหนดโดยใช้คำสั่ง ดังนั้นใครก็ตามที่อ่านสิ่งนี้โปรดอย่าสับสนนี่ไม่ได้ใช้คำสั่งแบบมีเงื่อนไข (เช่นซึ่งหมายถึงการเพิ่มหรือลบคำสั่งให้กับโดมตามเงื่อนไข)


3
คุณใช้คำสั่งในทั้งสองกรณีโดยมีตัวเลือกต่างกัน (เช่นสีส้มหรือสีเขียว) คำถามขอให้เพิกเฉยต่อคำสั่งเลยตามเงื่อนไข
Mojtaba
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.