Áp dụng chỉ thị có điều kiện


109

Tôi đang sử dụng Vật liệu 2 để thêm md-raised-button. Tôi chỉ muốn áp dụng chỉ thị này nếu điều kiện nhất định trở thành đúng.

Ví dụ:

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

Một ví dụ khác: Tôi đã tạo một dạng phản ứng động cơ bản trong plunker. Tôi đang sử dụng formArrayNamechỉ thị của biểu mẫu phản ứng cho mảng điều khiển. Tôi chỉ muốn áp dụng formArrayNamechỉ thị nếu điều kiện cụ thể trở thành đúng, nếu không thì không thêm formArrayNamechỉ thị.

Đây là một liên kết plunker .


Có md-
raise

Việc áp dụng các điều kiện mà chỉ thị được sử dụng có thể khiến AoT trở nên vô dụng vì bạn sẽ không thể biên dịch các mẫu trừ khi ứng dụng đang chạy.
Reactgular,

Câu trả lời:


54

Tôi không biết liệu bạn có thể áp dụng các chỉ thị dựa trên một điều kiện hay không, nhưng cách giải quyết sẽ là có 2 nút và hiển thị chúng dựa trên một điều kiện .

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

Chỉnh sửa: có thể điều này sẽ hữu ích.


13
Cảm ơn bạn đã phản hồi. Nhưng tôi đã sử dụng kỹ thuật này trong ví dụ plunker mà tôi đã thêm vào chi tiết câu hỏi. Đây là lựa chọn tốt nhưng không phải là ý kiến ​​hay nếu mã phức tạp. Bởi vì kỹ thuật này làm hỏng khái niệm sử dụng lại. Bạn có thể xem ví dụ của tôi trong plunker và nhận thấy cách mã của tôi bị trùng lặp vì cách tiếp cận này. Đó là lý do tại sao tôi không muốn sử dụng kỹ thuật này. Tôi muốn một số giải pháp tốt hơn để tôi có thể tạo các phần tử động với.
dùng2899728

1
Tôi hiểu rồi. Bạn có thể bọc mã được sao chép trong thành phần.
LLL

3
Đó là một ý tưởng hay nhưng tiếc là nó không hoạt động trong trường hợp các dạng phản ứng. Với các hình thức phản ứng, một vấn đề khác xuất hiện. Nếu tôi đặt đầu vào vào thành phần riêng biệt, thì góc sẽ yêu cầu tôi thêm [formGroup] = "form" trong thành phần con đó. Nhưng nếu tôi làm như vậy thì liên kết mảng của tôi sẽ không hoạt động.
dùng2899728

15
Đó là một giải pháp khủng khiếp vì nó trùng lặp mã. Hãy tưởng tượng nó không chỉ là nút mà là một div với rất nhiều mã html bên trong nó.
Shachar Har-Shuv

87

Nếu bạn chỉ cần thêm một thuộc tính để kích hoạt các quy tắc CSS, bạn có thể sử dụng phương pháp dưới đây: (điều này không tự động tạo / hủy một chỉ thị)

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

Áp dụng tương tự cho plunker: fork của bạn

Cập nhật:

Cách condition ? '' : nullhoạt động như giá trị:

Khi ''nó trở thành chuỗi rỗng ( ) attr.md-raised-button="", khi đó nullthuộc tính của nó sẽ không tồn tại.

Cập nhật: cập nhật plunker: fork (các vấn đề về phiên bản đã được khắc phục, xin lưu ý rằng câu hỏi ban đầu dựa trên góc 4)


@Luke Có, nếu bạn muốn nói "(bây giờ)" là: kể từ ngày 1 tháng 1 năm 2017, tức là 5 tháng trước khi câu hỏi được hỏi. xem mục thứ 6 thay đổi góc cạnh
Aldracor

@Aldracor angle 5.2.1, không hoạt động. Và tôi không hiểu tại sao sự kiện lại giống như "condition? '': Null" trong đó cả hai kết quả về cơ bản đều sai. Cái gì nên được thay vì ''? 'true' cũng không hoạt động.
Arsenii Fomin

1
để cho bất cứ ai doesnt muốn tạo một yếu tố html để cho chỉ thị của họ để làm việc và đang sử dụng ng-container, tôi chỉ đi với đi qua trong một [kích hoạt] = "booleanVar"
Ben Taliadoros

7
Không hoạt động đối với tôi trong Angular 6. Mẫu plunker không vượt qua được màn hình tải. Dựa trên bài đọc của tôi, cách tiếp cận này có thể hoạt động đối với các thuộc tính HTML, nhưng sẽ không hoạt động đối với các chỉ thị Angular. Câu hỏi ban đầu là về Angular Directives từ thư viện tài liệu ng.
JeffryHouser

6
@kbpontius cảm ơn bạn đã nhận xét, nó hoạt động trên các thuộc tính Html nhưng không hoạt động trên các chỉ thị góc cạnh (dưới dạng thuộc tính)
Reza

19

Như đã lưu ý, điều này dường như không khả thi. Một thứ có thể được sử dụng để ít nhất là ngăn chặn một số trùng lặp là ng-template. Điều này cho phép bạn trích xuất nội dung của phần tử bị ảnh hưởng bởi sự ngIfphân nhánh.

Ví dụ: nếu bạn muốn tạo một thành phần menu phân cấp bằng 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>

Ở đây, chỉ thị áp dụng có điều kiện là matMenuTriggerFor, chỉ nên áp dụng cho các món trong thực đơn có trẻ em. Nội dung của nút được chèn vào cả hai nơi qua ngTemplateOutlet.


6
Đây là câu trả lời duy nhất cho phép một nhà phát triển sử dụng các lệnh có điều kiện cũng như khả năng tái sử dụng mã.
Ravinder Payal

16

Điều này có thể đến muộn, nhưng nó là một phương pháp khả thi và thanh lịch để áp dụng một chỉ thị có điều kiện.

Trong lớp chỉ thị, hãy tạo biến đầu vào:

@Input('myDirective') options: any;

Khi áp dụng chỉ thị, hãy đặt thuộc tính áp dụng của biến đầu vào:

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

Trong phương thức của lệnh kiểm tra biến this.options.apply và áp dụng logic chỉ thị dựa trên điều kiện:

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

    // directive logic
}

3
Điều này không hiệu quả với tôi, vì chỉ thị vẫn tồn tại trong thành phần, nó chỉ thực hiện không logic. Tôi muốn sự tồn tại của chỉ thị được áp dụng có điều kiện, cụ thể là vì có css kiểm tra chỉ thị này.
Ran Lottem

Bạn gặp sự cố khác với sự cố được liệt kê ở đây (Áp dụng chỉ thị có điều kiện). Đăng vấn đề của bạn và mọi người sẽ giúp bạn. Như ý tưởng đầu tiên, bạn có thể đặt chỉ thị trên một div và đặt một ng-container với * ngIf xung quanh nó để áp dụng điều kiện của bạn. ngNếu xóa nút div khỏi DOM, thì nó có thể hoạt động. Tôi chỉ đoán, bạn cần đăng vấn đề của bạn với các mẫu mã / mô tả để ppl giúp bạn.
Tiha

Đây không phải là một giải pháp tốt. Chỉ thị vẫn được khởi tạo.
Dino

8

Như những người khác cũng đã nêu, directiveskhông thể được áp dụng động.

Tuy nhiên, nếu bạn chỉ muốn chuyển đổi md-buttonkiểu của từ phẳng sang nâng , thì đây là

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

sẽ thực hiện thủ thuật. Plunker


3

Đây cũng có thể là một giải pháp:

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


Nó hoạt động cho góc 4, ion 3 như thế này:

[color]="condition ? 'primary' : ''"đâu conditionlà một chức năng quyết định xem đây có phải là trang đang hoạt động hay không. Toàn bộ mã trông như thế này:

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


2

Hiện tại, có một NOcách để áp dụng có điều kiện một chỉ thị cho một thành phần, điều này không được hỗ trợ. Các thành phần mà bạn đã tạo có thể được thêm hoặc bớt có điều kiện.

Đã có một vấn đề được tạo ra cho cùng một vấn đề angular2, vì vậy nó cũng sẽ xảy ra với trường hợp của angle4.

Ngoài ra, bạn có thể chọn tùy chọn với ng-if

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

1
đã được đề cập trong câu trả lời của LLL
Sumit Ramteke

2

Tôi không thể tìm thấy một giải pháp hiện có tốt, vì vậy tôi đã xây dựng chỉ thị của riêng mình để thực hiện điều này.

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

Sau đó, html của bạn:

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


Bạn có thể chỉ sử dụng một @HostBinding('attr.dynamic-attr') @Input('dynamic-attr') attr: string;thay vì ngOnInit + ElementRef.
pinguinjkeke

2
Đây không phải là câu trả lời cho câu hỏi làm thế nào để thêm động một chỉ thị , không phải một thuộc tính.
Chris Haines

2

Có thể nó sẽ giúp ích cho ai đó.

Trong ví dụ dưới đây, tôi có my-button.component.htmlvà tôi muốn áp dụng *appHasPermissionchỉ thị cho <button>chỉ nếu rolethuộc tính được đặt.

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

Bằng cách đó, bạn không trùng lặp <button>mã.


0

vâng nó là có thể.

trang html với chỉ thị 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>

chỉ thị

@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
Là một mặt lưu ý, các Renderer bị phản đối, thay vì sử dụng Renderer2: alligator.io/angular/using-renderer2
tam.teixeira

0

Chuyển nullđến chỉ thị loại bỏ nó!

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

-1

Sử dụng NgClass

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

ví dụ về điều kiện đúng:

this.element === 'Today'

hoặc một hàm boolean

getTruth()

đầy đủ ví dụ:

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

Nếu bạn muốn một lớp mặc định:

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

6
Đây không phải là những gì tôi đã hỏi. Bạn đang hiển thị ví dụ cho lớp học. Tôi đang nói về chỉ thị thuộc tính.
dùng2899728

@ user2899728 Rất tiếc, không có cách nào khác để làm điều đó. (Bạn không thể đặt md-raised-buttonthuộc tính là false)
Edric

@ user2899728 Không có cách nào để áp dụng chỉ thị một cách có điều kiện. Tôi đã cố gắng cung cấp cho bạn những gì bạn đang tìm kiếm (kết quả cuối cùng) bằng một cách tiếp cận khác ("phương tiện").
Moshe

Khi bạn đưa ra một giải pháp thay thế sáng tạo, trước tiên bạn nên đưa vào một dòng nhận xét để mô tả bạn đang đi đâu với câu trả lời của mình.
bvdb

1
@bvdb cảm ơn vì những lời tốt đẹp của bạn. Tôi đã viết mà không có định hướng, và đó là một sai lầm. Trong tương lai, tôi hy vọng sẽ chỉnh sửa bài đăng này, vì nó có thể giúp ích cho một người.
Moshe

-1

Tôi có một ý tưởng khác về những gì bạn có thể làm.

Bạn có thể lưu trữ html mà bạn muốn thay thế trong một biến dưới dạng chuỗi và sau đó thêm / xóa chỉ thị khỏi nó như bạn muốn, bằng cách sử dụng bypassSecurityTrustHtmlphương thức của DomSanitizer .

Tôi không dẫn đến một giải pháp sạch nhưng ít nhất bạn không cần phải lặp lại mã.


-3

Vào ngày 18 tháng 1 năm 2019, Đây là cách tôi thêm chỉ thị có điều kiện trong Angular 5 trở lên. Tôi cần thay đổi màu sắc của <app-nav>thành phần dựa trên darkMode. Nếu trang ở chế độ tối hay không.

Điều này đã làm việc cho tôi:

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

Tôi hi vọng điêu nay se giup được ai đo.

BIÊN TẬP

Điều này thay đổi giá trị của một thuộc tính (màu) dựa trên một điều kiện. Nó chỉ xảy ra rằng màu được xác định bằng cách sử dụng một chỉ thị. Vì vậy, bất kỳ ai đọc điều này, xin đừng nhầm lẫn, đây không phải là áp dụng chỉ thị có điều kiện (nghĩa là thêm hoặc xóa chỉ thị vào dom dựa trên một điều kiện)


3
Bạn áp dụng chỉ thị trong cả hai trường hợp chỉ với các tùy chọn khác nhau (ví dụ: màu cam hoặc màu xanh lá cây). Câu hỏi yêu cầu bỏ qua chỉ thị dựa trên một điều kiện.
Mojtaba
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.