조건부로 지시문 적용


109

재료 2를 사용하여 md-raised-button. 특정 조건이 충족되는 경우에만이 지침을 적용하고 싶습니다.

예를 들면 :

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

또 다른 예 : 플 런커에서 기본 동적 반응 형을 만들었습니다. formArrayName컨트롤 배열에 반응 형 지시문을 사용 하고 있습니다. formArrayName특정 조건이 참인 경우에만 지시문 을 적용하고 , 그렇지 않으면 formArrayName지시문을 추가하지 않습니다 .

여기에 플 런커 링크가 있습니다.


예 md-raised-button 속성 지시문입니다 ( 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
좋은 생각이지만 불행히도 반응 형의 경우에는 작동하지 않습니다. 반응 형에서는 또 다른 문제가 나타납니다. 입력을 별도의 구성 요소에 넣으면 angular는 해당 자식 구성 요소 내에 [formGroup] = "form"을 추가해야합니다. 그러나 그렇게하면 배열 바인딩이 작동하지 않습니다.
user2899728

15
중복 코드이기 때문에 끔찍한 솔루션입니다. 버튼이 아니라 내부에 많은 html 코드가있는 div라고 상상해보십시오.
Shachar Har-Shuv

87

CSS 규칙을 트리거하기 위해 속성 만 추가해야하는 경우 아래 방법을 사용할 수 있습니다. (이는 지시문을 동적으로 생성 / 파괴하지 않습니다.)

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

플 런커에 동일하게 적용 : 포크

최신 정보:

condition ? '' : null가치로 작동 하는 방법 :

빈 문자열 ( '') attr.md-raised-button=""일 때 null속성이 존재하지 않을 때이됩니다 .

업데이트 : plunker 업데이트 : fork (버전 문제 수정, 질문은 원래 각도 4를 기반으로했습니다)


@Luke 예, "(지금)" 을 의미하는 경우 : 2017-01-06 이후 질문이 제기되기 5 개월 전입니다. 참조 각도 변경 로그 6 항목
Aldracor

@Aldracor 각도 5.2.1, 작동하지 않습니다. 그리고 두 결과가 모두 기본적으로 거짓 인 "condition? '': null"처럼 보이는 이유를 이해하지 못합니다. ''대신 무엇을해야합니까? 'true'도 작동하지 않습니다.
Arsenii Fomin

1
그래서 일에 자신의 지시어 위해 HTML 요소를 만들 나던와 겨 컨테이너를 사용하는 사람을 위해, 난 그냥 [사용 가능] = "booleanVar"전달 갔다
벤 Taliadoros

7
Angular 6에서는 작동하지 않습니다. plunker 샘플이 로딩 화면을 지나치지 않습니다. 필자가 읽은 바에 따르면이 접근 방식은 HTML 속성에는 작동 할 수 있지만 Angular 지시문에는 작동하지 않습니다. 원래 질문은 ng 재료 라이브러리의 Angular Directives에 관한 것이 었습니다.
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에 지시문을 넣고 주변에 * ngIf가있는 ng-container를 넣어 조건을 적용 할 수 있습니다. ngIf는 DOM에서 div 노드를 제거하므로 작동 할 수 있습니다. 나는 당신을 돕기 위해 ppl에 대한 코드 샘플 / 설명으로 문제를 게시해야한다고 생각합니다.
Tiha

이것은 좋은 해결책이 아닙니다. 지시문은 여전히 ​​초기화됩니다.
Dino

8

다른 사람들도 언급했듯이 directives동적으로 적용될 수 없습니다.

방금 전환하려는 경우, md-button에서의 스타일을 평면올려 다음이,

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

트릭을 할 것입니다. 플 런커


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컴포넌트에 디렉티브를 조건부로 적용하는 방법이 있으며 이는 지원되지 않으며, 생성 한 컴포넌트는 조건부로 추가 또는 제거 할 수 있습니다.

에서 이미 생성 된 문제가 있으므로 angular2angular4에서도 마찬가지입니다.

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


@HostBinding('attr.dynamic-attr') @Input('dynamic-attr') attr: string;ngOnInit + ElementRef 대신 a 를 사용할 수 있습니다 .
pinguinjkeke

2
이것은 속성이 아니라 동적으로 지시문 을 추가하는 방법에 대한 질문에 대한 대답이 아닙니다 .
Chris Haines 19

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

네 가능합니다.

appActiveAhover 지시문이있는 html 페이지 :)

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

0

null지시문에 전달 하면 제거됩니다!

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

-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을 문자열로 변수에 저장 한 다음 DomSanitizerbypassSecurityTrustHtml 메서드를 사용하여 원하는대로 지시문을 추가 / 제거 할 수 있습니다 .

깨끗한 솔루션을 제공하지는 않지만 적어도 코드를 반복 할 필요는 없습니다.


-3

2019 년 1 월 18 일에 Angular 5 이상에서 조건부로 지시문을 추가 한 방법입니다. 을 <app-nav>기반으로 구성 요소 의 색상을 변경해야 했습니다 darkMode. 페이지가 어두운 모드에 있는지 여부.

이것은 나를 위해 일했습니다.

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

누군가에게 도움이되기를 바랍니다.

편집하다

조건에 따라 속성 (색상)의 값을 변경합니다. 색상은 지시문을 사용하여 정의됩니다. 따라서 이것을 읽는 사람은 혼동하지 마십시오. 이것은 조건부로 지시문을 적용하는 것이 아닙니다 (즉, 조건에 따라 dom에 지시문을 추가하거나 제거하는 것을 의미합니다).


3
두 경우 모두 다른 옵션 (예 : 주황색 또는 녹색)으로 지시문을 적용합니다. 질문은 조건에 따라 지시문을 전혀 무시하도록 요구합니다.
Mojtaba
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.