有条件地应用指令



>我正在使用材料 2 添加md-raised-button .我想仅在某些条件变为真时才应用此指令。

例如:

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

再比如:我在 plunker 中创建了一个基本的动态反应形式。我正在为控件数组使用响应式formArrayName指令。我想仅在特定条件变为真时才应用formArrayName指令,否则不要添加formArrayName指令。

这是一个 plunker 链接。

如果你只需要添加一个属性来触发CSS规则,你可以使用以下方法: (这不会动态创建/销毁指令(

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

同样应用于您的 plunker:叉

更新:

condition ? '' : null如何作为值工作:

当它是空字符串(''(时,它变成attr.md-raised-button="",当它null属性时将不存在。

更新:

plunker 更新:fork(版本问题已修复,请注意该问题最初基于 angular 4(

我不知道

您是否可以根据条件应用指令,但解决方法是有 2 个按钮并根据条件显示它们

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

编辑:也许这会有所帮助。

如前所述,这似乎是不可能的。至少可以用来防止一些重复的一件事是 ng-template .这允许您提取受ngIf分支影响的元素的内容。

例如,如果要使用 Angular 材质创建分层菜单组件:

<!-- 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 插入到两个位置。

这可能来得晚,但这是有条件地应用指令的可行且优雅的方法。

在指令类中创建输入变量:

@Input('myDirective') options: any;

应用指令时,设置输入变量的应用属性:

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

在指令的方法中,检查变量 this.options.apply 并根据条件应用指令逻辑:

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

正如其他人也指出的那样,directives不能动态应用。

但是,如果您只想将md-button的样式从平面切换到凸起,那么这个

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

会做这个伎俩。普伦克

目前,NO方法可以将指令有条件地应用于组件。不支持此操作。可以有条件地添加或删除已创建的组件。

已经有一个问题已经

angular2 创建了相同的问题,所以 angular4 也应该如此。

或者,您可以选择使用 ng-if 的选项

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

也许它会帮助某人。

在下面的示例中,我有my-button.component.html,并且只有在设置了 role 属性时才要将 *appHasPermission 指令应用于<button>

<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>代码。

这也可能是一个解决方案:

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


它适用于角 4、离子 3,如下所示:

[color]="condition ? 'primary' : ''"其中condition是一个决定这是否是活动页面的函数。整个代码如下所示:

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

null传递给指令会删除它!

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

我正在使用Angular Material,在*ngIf上添加一个元素对我来说不起作用(该元素会在许多新生成的材料 HTML 标签中消失,哈哈(。

我不知道这是否是一种好的做法,但我使用了OnChanges并且我有一种有条件的指令 - 它奏效了! :)

所以我就是这样解决的:

import { Directive, Renderer2, ElementRef, Input, OnChanges, SimpleChanges, AfterViewInit } from '@angular/core';
@Directive({
  selector: '[appDirtyInputIndicator]'
})
export class DirtyInputIndicatorDirective implements OnChanges, AfterViewInit {
  @Input('appDirtyInputIndicator') dirtyInputIndicator: boolean;
  span = this.renderer.createElement('span');
  constructor(private renderer: Renderer2, private el: ElementRef) {}
  ngOnChanges(changes: SimpleChanges): void {
    if (changes.dirtyInputIndicator && this.dirtyInputIndicator) {
      this.renderer.appendChild(this.el.nativeElement, this.span);
    } else {
      this.renderer.removeChild(this.el.nativeElement, this.span);
    }
  }
  ngAfterViewInit() {
    this.renderer.addClass(this.span, 'dirty_input_badge');
  }
}

我找不到一个很好的现有解决方案,所以我构建了自己的指令来做到这一点。

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>

我遇到了同样的问题,能够这样做:

组件.html

<tr *ngFor="let Qus of finalModel | paginate:{itemsPerPage: 10, currentPage:p}">
<td appHighlightUsa  [isUsa]="Qus.country=='United States' ? true :false">{{Qus.id | flags}}</td>
<td appHighlightUsa  [isUsa]="Qus.country=='United States' ? true :false">{{Qus.accociateId}}</td>
<td appHighlightUsa  [isUsa]="Qus.country=='United States' ? true :false" >{{Qus.country}}</td>
<td appHighlightUsa  [isUsa]="Qus.country=='United States' ? true :false" >{{Qus.country}}</td>
</tr>

我找到了一种解决方法,不仅可以有条件地对元素应用一个指令,还可以应用多个指令。您可以在组件中设置所需的任何条件,然后在模板中使用它们,如下所示:

  <div>
    <input type="text"> <- This is the targeted element.
    <div *ngIf="someCondition"
         someDirective>
    </div>
    <div *ngIf="anotherCondition"
         anotherDirective>
    </div>
  </div>

在指令中,您可以使用 elementRef 选择父节点,即包装div,然后选择第一个子节点,该子节点将始终是您要应用指令的元素。

@Directive({
  selector: '[someDirective]'
})
export class SomeDirective implements OnInit {
  constructor(private elementRef: ElementRef) {}
  ngOnInit(): void {
    const directiveElement = this.elementRef.nativeElement.parentNode.children[0];
  }
}

我对你能做什么有了另一个想法。

您可以将要替换的html作为字符串存储在变量中,然后使用DomSanitizer的bypassSecurityTrustHtml方法根据需要从中添加/删除指令。

我没有产生一个干净的解决方案,但至少你不需要重复代码。

是的,这是可能的。

html page with 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');
    }
  }
}

截至2019年1月18日,这就是我在 Angular 5 及更高版本中有条件地添加指令的方式。我需要根据darkMode更改<app-nav>组件的颜色。页面是否处于暗模式。

这对我有用:

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

我希望这对某人有所帮助。

编辑

这将根据条件更改属性(颜色(的值。碰巧颜色是使用指令定义的。所以任何阅读本文的人请不要感到困惑,这不是有条件地应用指令(即这意味着根据条件向 dom 添加或删除指令(

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

最新更新