Koşullu bir yönerge uygulayın


112

Eklemek için Materyal 2 kullanıyorum md-raised-button . Bu yönergeyi yalnızca belirli koşullar gerçekleştiğinde uygulamak istiyorum.

Örneğin:

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

Başka bir örnek: Plunker'da temel bir dinamik reaktif form oluşturdum. formArrayNameDenetim dizisi için reaktif form yönergesini kullanıyorum . formArrayNameYönergeyi yalnızca belirli bir koşul doğru olduğunda uygulamak istiyorum , aksi takdirde eklemeyinformArrayName yönerge .

İşte bir plunker bağlantısı .


Evet md-yükseltilmiş-düğme, öznitelik yönergesidir ( material.angular.io/components/component/button )
user2899728

Yönergelerin kullanıldığı koşulların uygulanması, uygulama çalışmadığı sürece şablonları derleyemeyeceğiniz için büyük olasılıkla AoT'yi işe yaramaz hale getirecektir.
Reactgular

Yanıtlar:


55

Bir koşula göre yönergeleri uygulayıp uygulayamayacağınızı bilmiyorum, ancak bir geçici çözüm 2 düğmeye sahip olmak ve bunları bir koşula göre görüntülemek olabilir .

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

Düzenleme: belki bu yardımcı olacaktır.


13
Cevabınız için teşekkürler. Ama bu tekniği soru detayında eklediğim plunker örneğinde zaten kullandım. Bu iyi bir seçenektir, ancak kod karmaşıksa iyi bir fikir değildir. Çünkü bu teknik yeniden kullanma kavramını mahvediyor. Örneğimi plunker'da görebilir ve bu yaklaşım sayesinde kodumun nasıl çoğaltıldığını görebilirsiniz. Bu yüzden bu tekniği kullanmak istemiyorum. İle dinamik öğeler oluşturabilmek için daha iyi bir çözüm istiyorum.
user2899728

1
Anlıyorum. Bileşende çoğaltılan kodu sarmalayabilirsiniz.
LLL

3
İyi fikir ama ne yazık ki reaktif formlarda işe yaramıyor. Reaktif formlarda başka bir sorun ortaya çıkar. Girdiyi ayrı bir bileşene koyarsam, açısal, o alt bileşene de [formGroup] = "form" eklememi gerektirir. Ama bunu yaparsam, dizi bağlamam çalışmaz.
user2899728

15
Yinelenen kod olduğu için bu korkunç bir çözüm. Bunun sadece düğme olmadığını, içinde çok sayıda html kodu bulunan bir div olduğunu hayal edin.
Shachar Har-Shuv

Dahil etmek gerekli değildir formGroupsarar bir çocuk bileşenine inputsenin kadar sadece geçebilir formControlbir şekilde @Input() control: FormControlsarıcı bileşeni içinde ve yerli uygulamak inputyoluyla[formControl]="control"
Oleg Kuibar

88

CSS kurallarını tetiklemek için bir öznitelik eklemeniz gerekiyorsa, aşağıdaki yöntemi kullanabilirsiniz: (bu, bir yönergeyi dinamik olarak oluşturmaz / yok etmez)

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

Aynı şeyi sizin dalıcınıza da uyguladınız: çatal

Güncelleme:

condition ? '' : nullDeğer olarak nasıl çalışır:

Boş dizge ( '') attr.md-raised-button=""olduğunda null, özniteliği olmayacağı zaman olur .

Güncelleme: plunker güncelleme: çatal (sürüm sorunları giderildi, lütfen sorunun başlangıçta açısal 4'e dayandığını unutmayın)


@Luke Evet, soru sorulmadan 5 ay önce "(şimdi)" ile kastınız: 2017-01-06'dan beri. açısal değişiklik
günlüğüne

@Aldracor açısal 5.2.1, çalışmıyor. Ve neden "durum": null "gibi görünmesi gerektiğini anlamıyorum, burada her iki sonuç da temelde yanlıştır. '' Yerine ne olmalı? "true" da çalışmıyor.
Arsenii Fomin

1
bu yüzden direktiflerinin çalışması için bir html öğesi oluşturmak istemeyen ve ng-konteyner kullanan herkes için, sadece [etkin] = "booleanVar"
Ben Taliadoros

7
Benim için Angular 6'da çalışmıyor. Plunker örneği yükleme ekranını geçmiyor. Okumama dayalı olarak, bu yaklaşım HTML öznitelikleri için işe yarayabilir, ancak Angular yönergeleri için çalışmayacaktır. İlk soru, ng malzeme kitaplığındaki Açısal Yönergeler hakkındaydı.
JeffryHouser

6
@kbpontius yorumunuz için teşekkürler, Html özniteliklerinde çalışır, ancak açısal yönergelerde çalışmaz (öznitelik olarak)
Reza

19

Daha önce de belirtildiği gibi, bu mümkün görünmüyor. En azından bazı kopyaları önlemek için kullanılabilecek bir şey ng-template. Bu, etkilenen öğenin içeriğini çıkarmanıza olanak sağlar.ngIf dallanmadan .

Örneğin, Açısal Malzeme kullanarak hiyerarşik bir menü bileşeni oluşturmak istiyorsanız:

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

Burada koşullu olarak uygulanan yönerge, matMenuTriggerForyalnızca çocuklu menü öğelerine uygulanması gereken dir. Düğmenin içeriği, aracılığıyla her iki yere de eklenir ngTemplateOutlet.


6
Bu, bir geliştiricinin koşullu yönergeleri ve kod yeniden kullanılabilirliğini kullanmasına izin veren tek cevaptır.
Ravinder Payal

16

Bu geç gelebilir, ancak şartlı olarak bir yönergeyi uygulamak için uygun ve zarif bir yöntemdir.

Yönerge sınıfında girdi değişkenini oluşturun:

@Input('myDirective') options: any;

Yönergeyi uygularken, girdi değişkeninin uygulama özelliğini ayarlayın:

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

Yönerge yönteminde, this.options.apply değişkenini kontrol edin ve koşula bağlı olarak yönerge mantığını uygulayın:

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

    // directive logic
}

3
Yönerge bileşende hala mevcut olduğundan, bu benim için işe yaramıyor, sadece mantık yürütmüyor. Direktifin varlığının şartlı olarak uygulanmasını istiyorum, özellikle de bu direktifi kontrol eden css var.
Ran Lottem

Burada listelenenden farklı bir sorununuz var (Yönergeyi şartlı uygulayın). Sorununuzu gönderin ve insanlar size yardımcı olsun. İlk fikir olarak, direktifinizi bir div üzerine koyabilir ve koşulunuzu uygulamak için etrafına * ngIf olan bir ng-konteyner koyabilirsiniz. ngIf, div düğümünü DOM'dan kaldırır, bu yüzden işe yarayabilir. Sadece tahmin ediyorum, probleminizi size yardımcı olması için ppl için kod örnekleri / açıklaması ile göndermeniz gerekiyor.
Tiha

Bu iyi bir çözüm değil. Yönerge hala başlatılıyor.
Dino

8

Başkalarının da belirttiği directivesgibi dinamik olarak uygulanamaz.

Sadece geçiş yapmak istiyorsanız, ancak md-buttongelen 'ın stil düz için kaldırdı o zaman bu,

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

hile yapardı. Plunker


3

Bu da bir çözüm olabilir:

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


Açısal 4, iyonik 3 için şu şekilde çalışıyor:

[color]="condition ? 'primary' : ''"conditionbunun etkin bir sayfa olup olmadığına karar veren bir işlev nerede . Kodun tamamı şöyle görünür:

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


2

Şu anda, NObir bileşene koşullu olarak bir yönerge uygulamanın bir yolu vardır. Bu desteklenmez. Oluşturduğunuz bileşenler koşullu olarak eklenebilir veya kaldırılabilir.

Zaten aynı için oluşturulmuş bir sorun var angular2 , bu nedenle angular4 de durum böyle olmalıdır.

Alternatif olarak, seçeneğe ng-if ile gidebilirsiniz.

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


2

Güzel bir mevcut çözüm bulamadım, bu yüzden bunu yapan kendi yönergemi oluşturdum.

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

Sonra html'niz:

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


@HostBinding('attr.dynamic-attr') @Input('dynamic-attr') attr: string;NgOnInit + ElementRef yerine sadece a kullanabilirsiniz .
pinguinjkeke

2
Bu, bir nitelik değil, dinamik olarak bir direktifin nasıl ekleneceği sorusunun cevabı değildir.
Chris Haines

2

Belki birine yardımcı olur.

Aşağıdaki örnekte elimde var my-button.component.htmlve *appHasPermissionyönergeyi <button>yalnızca roleöznitelik ayarlanmışsa uygulamak istiyorum .

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

Bu şekilde <button>kodu çoğaltmazsınız .


0

Evet mümkün.

appActiveAhover yönergesine sahip html sayfası :)

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

direktif

@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
Bir yan not olarak, Renderer kullanımdan kaldırıldı, bunun yerine Renderer2'yi kullanın: alligator.io/angular/using-renderer2
tam.teixeira

0

Yönergeye geçmek nullonu kaldırır!

<button md-raised-button="condition ? true : null"></button>

-1

Kullanım NgClass

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

gerçek koşul örneği:

this.element === 'Today'

veya bir boole işlevi

getTruth()

tam örnek:

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

Varsayılan bir sınıf istiyorsanız:

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

6
İstediğim bu değil. Sınıf için örnek oluyorsunuz. Öznitelik yönergesinden bahsediyorum.
user2899728

@ user2899728 Ne yazık ki bunu yapmanın başka yolu yok. ( md-raised-buttonÖzelliği yanlış olarak ayarlayamazsınız )
Edric

@ user2899728 Yönergeleri koşullu olarak uygulamanın bir yolu yoktur. Size aradığınız şeyi (nihai sonuç) farklı bir yaklaşımla ("araçlar") vermeye çalıştım.
Moshe

Yaratıcı bir alternatif sunduğunuzda, cevabınızla nereye gittiğinizi açıklamak için genellikle önce bir satır yorum koymak yardımcı olur.
bvdb

1
@bvdb nazik sözleriniz için teşekkür ederim. Yönsüz yazıyordum ve bu bir hataydı. Gelecekte, bir kişiye bile yardımcı olabileceği için bu gönderiyi düzenlemeyi umuyorum.
Moshe

-1

Ne yapabileceğin hakkında başka bir fikrim var.

Değiştirilmesini istediğiniz html'yi bir değişken içinde bir dizge olarak saklayabilir ve ardından DomSanitizerbypassSecurityTrustHtml yöntemini kullanarak yönergeyi istediğiniz gibi ekleyebilir / kaldırabilirsiniz .

Temiz bir çözüme ulaşmıyorum ama en azından kodu tekrarlamanıza gerek yok.


-3

18 Ocak 2019 itibariyle, Angular 5 ve üzeri sürümlere şartlı olarak bir yönerge ekledim. Buna <app-nav>göre bileşenin rengini değiştirmem gerekiyordu darkMode. Sayfa karanlık modda olup olmadığı.

Bu benim için çalıştı:

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

Umarım bu birine yardımcı olur.

DÜZENLE

Bu, bir koşula bağlı olarak bir niteliğin (renk) değerini değiştirir. Sadece bir yönerge kullanılarak renk tanımlanır. Yani bunu okuyan herkesin kafasını karıştırmayın, bu şartlı olarak bir direktif uygulamak değildir (yani, bir koşula bağlı olarak doma bir direktif eklemek veya kaldırmak anlamına gelir)


3
Direktifi her iki durumda da farklı seçeneklerle (yani turuncu veya yeşil) uygularsınız. Soru, bir koşula bağlı olarak direktifi göz ardı etmemizi ister.
Mojtaba
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.