可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using Material 2 to add md-raised-button
.
I want to apply this directive only if certain condition becomes true.
For example:
<button md-raised-button="true"></button>
Another example:
I created a basic dynamic reactive form in plunker.
I am using formArrayName
directive of reactive form for array of controls.
I want to apply formArrayName
directive only if specific condition becomes true. otherwise don't add formArrayName
directive. I tried and researched a lot but could find any solution.
Here is plunker link: https://plnkr.co/edit/oPZ7PyBSf8jjYa2KVh4J?p=preview
I would really appreciate any contribution.
Thanks in advance!
回答1:
I don't know if you can apply directives based on a condition, but a workaround would be having 2 buttons and display them based on a condition.
<button *ngIf="!condition"></button>
<button *ngIf="condition" md-raised-button></button>
Edit: maybe this will be helpful.
回答2:
You can use the below method:
<button [attr.md-raised-button]="condition ? '' : null"></button>
Applied the same to your plunker: fork
Update:
How condition ? '' : null
works as the value:
When its the empty string (''
) it becomes attr.md-raised-button=""
, when its null
the attribute will not exist.
Update: plunker update: fork (version issues fixed, please note the question was originally based on angular 4)
回答3:
This may come late, but it is a viable and elegant method for applying a directive conditionally.
In the directive class create the input variable:
@Input('myDirective') options: any;
When applying the directive, set the apply property of the input variable:
<div [myDirective] = {apply: someCondition}></div>
In the method of the directive check for the variable this.options.apply and apply the directive logic based on the condition:
ngAfterViewInit(): void {
if (!this.options.apply) {
return;
}
// directive logic
}
回答4:
As others have also stated, directives
can't be dynamically applied.
However, if you just want to toggle md-button
's style from flat to raised, then this
<button md-button [class.mat-raised-button]="isRaised">Toggle Raised Button</button>
would do the trick. Plunker
回答5:
As already noted this does not appear to be possible. One thing that can be used to at least prevent some duplication is ng-template
. This allows you to extract the content of the element affected by the ngIf
branching.
If you for example want to create a hierarchical menu component using 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>
Here the conditionally applied directive is matMenuTriggerFor
, which should only be applied to menu items with children. The contents of the button are inserted in both places via ngTemplateOutlet
.
回答6:
Currently, there is NO
way to conditionally apply a directive to a component.This is not supported.The components which you have created can be added or removed conditionally.
There is already an issue created for the same with angular2
, so it should be the case with angular4 aswell.
Alternatively you can go for the option with ng-if
<button ngIf="!condition"></button>
<button ngIf="condition" md-raised-button></button>
回答7:
yes it is possible.
html page with appActiveAhover directive :)
<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
@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');
}
}
}
回答8:
I couldn't find a nice existing solution, so i built my own directive which does this.
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);
}
}
Then your html:
<div dynamic-attr="{{hasMargin: 'margin-left' ? ''}}"></div>
回答9:
This could be a solution too:
[md-raised-button]="condition ? 'true' : ''"
It's working for angular 4, ionic 3 like this:
[color]="condition ? 'primary' : ''"
where condition
is a function that decides if this is an active page or not. The whole code look like this:
<button *ngFor="let page of ..." [color]="isActivePage(page) ? 'primary' : ''">{{ page.title }}</button>
回答10:
Use NgClass
[ngClass]="{ 'mat-raised-button': trueCondition }"
example of true condition:
this.element === 'Today'
or a boolean function
getTruth()
full example:
<button [ngClass]="{ 'mat-raised-button': trueCondition }">TEXT</button>
If you want a default class:
<button [ngClass]="{ 'mat-raised-button': trueCondition, 'default-class': !trueCondition }">TEXT</button>
回答11:
I got another idea about what you could do.
You could store the html you want replaced in a variable as a string and then add / remove the directive from it as you wish, using the bypassSecurityTrustHtml
method of the DomSanitizer.
I doesn't result in a clean solution but at least you don't need to repeat the code.
回答12:
As at 18th Jan 2019,
This is how I added a directive conditionally in Angular 5 and above. I needed to change the color of the <app-nav>
component based on darkMode
. If the page was in dark mode or not.
This worked for me:
<app-nav [color]="darkMode ? 'orange':'green'"></app-nav>
I hope this helps someone.