有条件地应用指令

我正在使用材质2来添加 md-raised-button。我想应用这个指令只有当某些条件成为真。

例如:

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

另一个例子: 我创建了一个基本的动态反应形式的柱塞。 我使用 formArrayName指令的反应形式的数组控制。 我想应用 formArrayName指令只有当特定条件成为真,否则不添加 formArrayName指令。

这是 柱塞杆柱塞杆柱塞杆

127296 次浏览

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

我不知道您是否可以根据条件应用指令,但是 解决办法将具有 2个按钮,并根据条件显示它们

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

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

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

对于 译自: 美国广播公司网站(angular2)已经有一个相同的问题,所以对于 angular4也应该是这样。

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

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

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

但是,如果你只是想切换 md-button的风格从 平的长大了,那么这

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

会有用的 强者

关于你的能力,我有另一个想法。

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

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

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

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


它适用于角度4,离子3是这样的:

其中 condition是一个函数,它决定这是否是一个活动页面。整个代码如下:

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

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

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

将同样的方法应用到你的活塞上: 叉子

更新:

condition ? '' : null作为值的工作原理:

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

更新: 柱塞更新: 叉子(版本问题已修复,请注意问题最初是基于角度4)

是的,有可能。

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


}

正如已经指出的那样,这似乎是不可能的。有一样东西至少可以用来防止某些重复,那就是 ng-template。这允许您提取受 ngIf分支影响的元素的内容。

例如,如果你想使用角度材质创建一个分层菜单组件:

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

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

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

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

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


// directive logic
}

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

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>

截至2019年1月18日, 这就是我如何在角度5及以上有条件地添加指令。我需要改变基于 darkMode<app-nav>组件的颜色。页是否处于暗模式。

这对我很有效:

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

我希望这能帮到别人。

剪辑

这会根据条件更改属性(颜色)的值。只是碰巧颜色是使用指令定义的。因此,任何人阅读本请不要混淆,这是不适用的指令条件(即。这意味着根据条件向 dom 添加或删除指令)

也许能帮到别人。

在下面的例子中,我有一个 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>代码。

null传递给指令会删除它!

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

我正在使用 Angular Material,在 *ngIf上添加一个元素对我来说不太适合(该元素将在许多新生成的材料 HTML 标记中消失 lol)。

我不知道这是否是一个好的实践,但是我使用了 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');
}
}