use @Attribute in custom attribute directive and data -binding attribute directive

Viewed 394

I'm new to Angular, just a question on use @Attribute in attribute directives, below is some code from a book:

@Directive({
 selector: "[pa-attr]",
})
export class PaAttrDirective {
    constructor(element: ElementRef, @Attribute("pa-attr") bgClass: string) {
       element.nativeElement.classList.add(bgClass || "bg-success", "text-white");
 }
}

and the template.html:

...
<td pa-attr="bg-warning">{{item.category}}</td>
...

so we can see that use @Attribute we can get the value of the attribute, but if we use data-binding attribute directive as:

<td [pa-attr]="item.category == 'Soccer' ? 'bg-info' : null">...

then the book modify the code as:

export class PaAttrDirective {
   constructor(private element: ElementRef) {}

   @Input("pa-attr")
   bgClass: string;

   ngOnInit() {
      this.element.nativeElement.classList.add(this.bgClass || "bg-success", "text-white");
   }
}

I'm a little bit confused here, can't we use @Attribute to get the value again as:

export class PaAttrDirective {
    constructor(element: ElementRef, @Attribute("pa-attr") bgClass: string) {
       element.nativeElement.classList.add(bgClass || "bg-success", "text-white");
 }
}

why when use the attribute directive with data-binding then we have to create input property in the code and not able to use @Attribute?

2 Answers

@Attribute: accepts plain primitive types, eg strings and numbers @Input: accepts anything/an object, eg your own class object

You pass the string abc to the attribute like this:

<td pa-attr="abc"></td>

You pass the same thing to the input like this:

<td [pa-attr]="'abc'"></td> <!-- note the single quotes -->

Or in ts

x = 'abc';

in html

<td [pa-attr]="x"></td> 

I am not sure if you can have a dash in the input property name.

They use @Input instead of @Attribute because:

Attributes initialize DOM properties and then they are done. Property values can change; attribute values can't.

item.category == 'Soccer' ? 'bg-info' : null expression changes attribute value, so your Directive wouldn't get the updated value after it was changed.

I suggest to read about Angular template syntax here.

Related