it-swarm.com.ru

Применить директиву условно

Я использую Материал 2, чтобы добавить md-raised-button.

Я хочу применять эту директиву, только если определенное условие становится истинным.

Например:

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

Другой пример: я создал базовую динамическую реактивную форму в плункере. Я использую директиву formArrayName реактивной формы для массива элементов управления. Я хочу применить директиву formArrayName, только если конкретное условие становится истинным. в противном случае не добавляйте директиву formArrayName. Я много пытался и исследовал, но мог найти любое решение.

Вот ссылка на плункер: https://plnkr.co/edit/oPZ7PyBSf8jjYa2KVh4J?p=preview

Я был бы очень признателен за любой вклад.

Заранее спасибо!

61
user2899728

Я не знаю, можете ли вы применять директивы, основанные на условии, но обходной путь будет иметь кнопки 2 и отображать их в зависимости от условия.

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

Правка: возможно это будет полезно.

24
LLL

Вы можете использовать следующий метод:

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

То же самое применимо к вашему плункеру: вилка

Обновление:

Как condition ? '' : null работает как значение:

Когда это пустая строка (''), он становится attr.md-raised-button="", когда его null атрибут не будет существовать.

Обновление: обновление плунжера: форк (исправлены проблемы с версией, обратите внимание, что вопрос изначально был основан на angular 4)

38
Aldracor

Это может произойти поздно, но это жизнеспособный и элегантный метод условного применения директивы.

В классе директивы создайте входную переменную:

@Input('myDirective') options: any;

При применении директивы установите свойство apply входной переменной:

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

В методе директивы проверьте переменную this.options.apply и примените директивную логику на основе условия:

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

    // directive logic
}
9
Tiha

Как уже говорили другие, directives не может применяться динамически.

Однако, если вы просто хотите переключить стиль md-button с flat на поднято, то это

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

сделал бы трюк. Плункер

7
Ankit Singh

Как уже отмечалось, это не представляется возможным. Одна вещь, которую можно использовать, чтобы хотя бы предотвратить некоторое дублирование, - это 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
H.B.

В настоящее время существует NO способ условного применения директивы к компоненту. Это не поддерживается. Созданные вами компоненты могут быть добавлены или удалены условно. 

Уже существует проблема, созданная для того же самого с angular2, так должно быть и в случае angular4.

В качестве альтернативы вы можете перейти к опции с помощью ng-if

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

Я не мог найти существующее решение Nice, поэтому я создал свою собственную директиву, которая делает это.

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>

2
Cappi10

да, это возможно.

hTML-страница с директивой 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>

директива

@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
Chaitanya Nekkalapudi

Это тоже может быть решением:

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


Это работает для Angular 4, ионных 3, как это:

[color]="condition ? 'primary' : ''" где condition - это функция, которая решает, является ли эта страница активной или нет. Весь код выглядит так:

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

1
zalog

По состоянию на 18 января 2019 года Так я условно добавил директиву в Angular 5 и выше. Мне нужно было изменить цвет компонента <app-nav> на основе darkMode. Если страница была в темном режиме или нет.

Это сработало для меня:

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

Я надеюсь, что это помогает кому-то.

0
Sandra israel

У меня есть еще одна идея о том, что вы могли бы сделать.

Вы можете сохранить html, который вы хотите заменить в переменной, в виде строки, а затем добавить/удалить директиву из нее, как хотите, используя метод bypassSecurityTrustHtml в DomSanitizer .

Я не приводил к чистому решению, но по крайней мере вам не нужно повторять код.

0
LLL