Terapkan arahan secara kondisional

109

Saya menggunakan Material 2 untuk menambahkan md-raised-button. Saya ingin menerapkan petunjuk ini hanya jika kondisi tertentu menjadi benar.

Sebagai contoh:

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

Contoh lain: Saya membuat bentuk reaktif dinamis dasar di plunker. Saya menggunakan formArrayNamedirektif bentuk reaktif untuk berbagai kontrol. Saya ingin menerapkan formArrayNamedirektif hanya jika kondisi tertentu menjadi benar, jika tidak, jangan tambahkan formArrayNamedirektif.

Berikut ini tautan plunker .

pengguna2899728
sumber
Ya md-diangkat-tombol itu direktif atribut ( material.angular.io/components/component/button )
pengguna2899728
Menerapkan kondisi di mana arahan digunakan kemungkinan akan membuat AoT tidak berguna karena Anda tidak akan dapat mengompilasi template kecuali aplikasi sedang berjalan.
Reactgular

Jawaban:

55

Saya tidak tahu apakah Anda dapat menerapkan arahan berdasarkan suatu kondisi, tetapi solusinya akan memiliki 2 tombol dan menampilkannya berdasarkan suatu kondisi .

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

Sunting: mungkin ini akan membantu.

LLL
sumber
13
Terima kasih atas tanggapan Anda. Tapi saya sudah menggunakan teknik ini dalam contoh plunker yang saya tambahkan dalam detail pertanyaan. Ini adalah opsi yang bagus tetapi bukan ide yang baik jika kodenya rumit. Karena karena teknik ini merusak konsep reuse. Anda dapat melihat contoh saya di plunker dan melihat bagaimana kode saya diduplikasi karena pendekatan ini. Itulah mengapa saya tidak ingin menggunakan teknik ini. Saya ingin solusi yang lebih baik sehingga saya dapat menghasilkan elemen dinamis dengan.
pengguna2899728
1
Saya melihat. Anda bisa membungkus kode yang digandakan dalam komponen.
LLL
3
Itu ide yang bagus tapi sayangnya itu tidak berhasil dalam kasus bentuk reaktif. Dengan formulir reaktif, masalah lain muncul. Jika saya memasukkan input ke dalam komponen terpisah, maka angular akan meminta saya untuk menambahkan [formGroup] = "form" dalam komponen anak itu juga. Tetapi jika saya melakukannya maka pengikatan array saya tidak akan berfungsi.
pengguna2899728
15
Itu solusi yang sangat buruk karena itu adalah kode duplikat. Bayangkan itu bukan hanya tombol tetapi div dengan banyak kode html di dalamnya.
Shachar Har-Shuv
87

Jika Anda hanya perlu menambahkan atribut untuk memicu aturan CSS, Anda dapat menggunakan metode di bawah ini: (ini tidak secara dinamis membuat / menghancurkan perintah)

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

Diterapkan sama untuk plunker Anda: garpu

Memperbarui:

Bagaimana condition ? '' : nullbekerja sebagai nilai:

Ketika string kosongnya ( '') menjadi attr.md-raised-button="", ketika nullatributnya tidak akan ada.

Pembaruan: pembaruan plunker: garpu (masalah versi diperbaiki, harap perhatikan pertanyaannya awalnya berdasarkan sudut 4)

Aldracor
sumber
@ Luke Ya, jika yang Anda maksud dengan "(sekarang)" sebagai: sejak 01-06 2017 yang 5 bulan sebelum pertanyaan diajukan. lihat
catatan perubahan
@Aldracor angular 5.2.1, tidak berfungsi. Dan saya tidak mengerti mengapa harus terlihat seperti "kondisi? '': Null" di mana kedua hasil pada dasarnya salah. Apa yang seharusnya menjadi pengganti ''? 'true' juga tidak berhasil.
Arsenii Fomin
1
jadi bagi siapa saja yang tidak ingin membuat elemen html agar direktif mereka berfungsi dan menggunakan ng-container, saya langsung saja meneruskan [enabled] = "booleanVar"
Ben Taliadoros
7
Tidak berfungsi untuk saya di Angular 6. Sampel plunker tidak dapat melewati layar pemuatan. Berdasarkan bacaan saya, pendekatan ini dapat berfungsi untuk atribut HTML, tetapi tidak akan berfungsi untuk arahan Angular. Pertanyaan asli tentang Angular Directives dari perpustakaan bahan ng.
JeffryHouser
6
@kbpontius terima kasih atas komentarnya, ini berfungsi pada atribut Html tetapi tidak pada arahan sudut (sebagai atribut)
Reza
19

Seperti yang telah disebutkan, hal ini tampaknya tidak mungkin dilakukan. Satu hal yang paling tidak dapat digunakan untuk mencegah duplikasi adalah ng-template. Ini memungkinkan Anda mengekstrak konten elemen yang terpengaruh oleh ngIfpercabangan.

Jika Anda misalnya ingin membuat komponen menu hierarki menggunakan 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>

Di sini direktif yang diterapkan secara kondisional matMenuTriggerFor, yang seharusnya hanya diterapkan ke item menu dengan turunan. Isi tombol disisipkan di kedua tempat melalui ngTemplateOutlet.

HB
sumber
6
Ini adalah satu-satunya jawaban yang memungkinkan pengembang untuk menggunakan arahan bersyarat serta kegunaan ulang kode.
Ravinder Payal
16

Ini mungkin datang terlambat, tetapi ini adalah metode yang layak dan elegan untuk menerapkan arahan secara bersyarat.

Di kelas direktif buat variabel input:

@Input('myDirective') options: any;

Saat menerapkan direktif, setel properti apply dari variabel input:

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

Dalam metode pemeriksaan direktif untuk variabel this.options.apply dan terapkan logika direktif berdasarkan kondisi:

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

    // directive logic
}
Tiha
sumber
3
Ini tidak berfungsi untuk saya, karena arahan masih ada di komponen, itu hanya tidak menjalankan logika. Saya ingin keberadaan direktif tersebut berlaku secara kondisional, khususnya karena ada css yang memeriksa arahan ini.
Ran Lottem
Anda memiliki masalah yang berbeda, dari yang tercantum di sini (Terapkan petunjuk secara bersyarat). Posting masalah Anda dan orang-orang akan membantu Anda. Sebagai ide pertama, Anda bisa meletakkan direktif pada div dan meletakkan wadah-ng dengan * ngIf di sekitarnya untuk menerapkan kondisi Anda. ngIf menghapus simpul div dari DOM, jadi itu mungkin berhasil. Saya hanya menebak, Anda perlu memposting masalah Anda dengan contoh kode / deskripsi untuk ppl untuk membantu Anda.
Tiha
Ini bukan solusi yang bagus. Petunjuk masih diinisialisasi.
Dino
8

Seperti orang lain juga menyatakan, directivestidak dapat diterapkan secara dinamis.

Namun, jika Anda hanya ingin mengubah md-buttongaya dari datar menjadi terangkat , maka ini

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

akan berhasil. Plunker

Ankit Singh
sumber
3

Ini juga bisa menjadi solusi:

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


Ini bekerja untuk sudut 4, ionik 3 seperti ini:

[color]="condition ? 'primary' : ''"di mana conditionfungsi yang memutuskan apakah ini halaman aktif atau tidak. Seluruh kode terlihat seperti ini:

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

zalog
sumber
2

Saat ini, ada NOcara untuk menerapkan arahan bersyarat ke sebuah komponen. Ini tidak didukung. Komponen yang telah Anda buat dapat ditambahkan atau dihapus secara bersyarat.

Sudah ada masalah yang dibuat untuk hal yang sama dengan angular2, jadi itu harus terjadi dengan angular4 juga.

Sebagai alternatif, Anda dapat menggunakan opsi ng-if

<button ngIf="!condition"></button>
<button ngIf="condition" md-raised-button></button> 
Sajeetharan
sumber
1
sudah tercakup dalam jawaban LLL
Sumit Ramteke
2

Saya tidak dapat menemukan solusi bagus yang ada, jadi saya membuat arahan saya sendiri yang melakukan ini.

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);
  }
}

Kemudian html Anda:

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

Cappi10
sumber
Anda dapat menggunakan hanya sebagai @HostBinding('attr.dynamic-attr') @Input('dynamic-attr') attr: string;pengganti ngOnInit + ElementRef.
pinguinjkeke
2
Ini bukan jawaban untuk pertanyaan bagaimana cara menambahkan direktif secara dinamis, bukan atribut.
Chris Haines
2

Mungkin itu akan membantu seseorang.

Dalam contoh di bawah ini saya memiliki my-button.component.htmldan saya ingin menerapkan *appHasPermissiondirektif <button>hanya jika roleatributnya disetel.

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

Dengan cara itu Anda tidak menduplikasi <button>kode.

MhagnumDw
sumber
0

ya itu mungkin.

html dengan direktif appActiveAhover :)

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

pengarahan

@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');
    }
  }

}
Chaitanya Nekkalapudi
sumber
2
Sebagai catatan tambahan, Renderer tidak digunakan lagi, sebagai gantinya gunakan Renderer2: alligator.io/angular/using-renderer2
tam.teixeira
0

Meneruskan nullke arahan menghapusnya!

<button md-raised-button="condition ? true : null"></button>
Yogesh Aggarwal
sumber
-1

Menggunakan NgClass

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

contoh kondisi sebenarnya:

this.element === 'Today'

atau fungsi boolean

getTruth()

contoh lengkap:

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

Jika Anda menginginkan kelas default:

  <button [ngClass]="{ 'mat-raised-button': trueCondition, 'default-class': !trueCondition }">TEXT</button>
Moshe
sumber
6
Ini bukan yang saya minta. Anda menunjukkan contoh untuk kelas. Saya berbicara tentang atribut-direktif.
pengguna2899728
@ user2899728 Sayangnya tidak ada cara lain untuk melakukannya. (Anda tidak dapat menyetel md-raised-buttonatribut sebagai false)
Edric
@ user2899728 Tidak ada cara untuk menerapkan arahan secara bersyarat. Saya telah mencoba memberikan apa yang Anda cari (hasil akhir) dengan pendekatan yang berbeda ("cara").
Moshe
Saat Anda menawarkan alternatif kreatif, biasanya akan membantu jika Anda memberikan sebaris komentar terlebih dahulu untuk menjelaskan tujuan Anda dengan jawaban Anda.
bvdb
1
@bvdb terima kasih atas kata-kata baik Anda. Saya menulis tanpa arah, dan itu adalah kesalahan. Kedepannya, saya berharap dapat mengedit postingan ini, karena dapat membantu bahkan satu orang.
Moshe
-1

Saya mendapat ide lain tentang apa yang dapat Anda lakukan.

Anda dapat menyimpan html yang ingin Anda ganti dalam variabel sebagai string dan kemudian menambahkan / menghapus arahan darinya sesuai keinginan, menggunakan bypassSecurityTrustHtmlmetode DomSanitizer .

Saya tidak menghasilkan solusi yang bersih tetapi setidaknya Anda tidak perlu mengulangi kode.

LLL
sumber
-3

Pada 18 Jan 2019, Beginilah cara saya menambahkan arahan bersyarat di Angular 5 ke atas. Saya perlu mengubah warna <app-nav>komponen berdasarkan darkMode. Jika halaman dalam mode gelap atau tidak.

Ini berhasil untuk saya:

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

Saya harap ini membantu seseorang.

EDIT

Ini mengubah nilai atribut (warna) berdasarkan suatu kondisi. Kebetulan warna ditentukan menggunakan arahan. Jadi siapa pun yang membaca ini mohon jangan bingung, ini tidak menerapkan arahan bersyarat (yaitu yang berarti menambah atau menghapus arahan ke dom berdasarkan suatu kondisi)

Sandra israel
sumber
3
Anda menerapkan arahan dalam kedua kasus hanya dengan opsi yang berbeda (mis., Oranye atau hijau). Pertanyaannya meminta untuk mengabaikan arahan sama sekali berdasarkan suatu kondisi.
Mojtaba