简体   繁体   中英

Dynamically add/change attribute on component selector

@Component({
    selector: 'ion-col',
    templateUrl: 'components-field.html'
})

export class FieldComponent {
    @HostBinding('attr.layout')
    layout = '¯\_(ツ)_/¯';
    element: any;
    constructor() {
        console.log('Hello ComponentsFieldComponent Component');
    }

    setElement(element) {
        this.element = element;
    }


}

In this example I can dynamically set the value of "layout" attribute. this example will do :

<ion-col layout="¯\_(ツ)_/¯"></ion-col>

BUT I want to set the name of the attribute dynamically in order to achieve this :

<ion-col col-3></ion-col>
<ion-col col-5></ion-col>
<ion-col col-12></ion-col>

I could create 12 versions of my component.I won't. Any idea ?

There isn't really an easy way to dynamically add or remove attributes via template binding in Angular, since attributes themselves are usually supposed to be static and have their values changed instead.

It's not impossible, though. I would recommend folding the logic into a directive:

@Directive({
   selector: '[colThing]'
})
export class ColThingDirective {

  @Input('colThing') 
  set colCriteria(value) {
   this.doLogicToChangeAttributes(value);
  }

  public attributeList = ['col-5', 'col-3'];

  constructor(private _r: Renderer2, private el: ElementRef) {}

  doLogicToChangeAttributes(value) {
    if (value === 'col-5-criteria') {
      this.removeAttributes();
      this._r.setAttribute(this.el.nativeElement, 'col-5', '');
    }

  }

  removeAttributes() {
    this.attributeList.forEach(s => this._r.removeAttribute(this.el.nativeElement, s));
  }
}

In component:

export class FieldComponent {

  @HostBinding('[ColThingDirective]') someCriteriaToChangeAttribute; // <--
 @Input to directive

}

Based on this use case, however, I'd be very surprised if there wasn't better built-in functionality behavior. I would have assumed that these attributes are either actually directives (which would need to be changed via a HostBinding ) or that there's some built-in way to handle what I assume is responsiveness. It's pretty unusual to have attributes there just for styling purposes.

The simplest I could come up with so far...

<ion-col [attr.col-12]="myValue === 'col-12' ? '' : null"
         [attr.col-6]="myValue === 'col-6' ? '' : null">

There is another way to add attribute in component selector (angular 12).

import {Component, ViewEncapsulation, ElementRef} from '@angular/core';

@Component({
  selector: 'user',
  templateUrl: './user.html',
  styleUrls: ['./user.scss'],
  encapsulation: ViewEncapsulation.None
})

export class User {
    constructor(private elementRef: ElementRef) { }

    ngOnInit(): void {
        let value = 'demo'; // value can be static or dynamic
        this.elementRef.nativeElement.setAttribute('key', value);
    }
}

Output -

<user key="demo">...</user>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM