Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does simply [myHighlight]="..." work for an attribute directive?

The myHighlight attribute directive in the dev guide uses the myHighlight name as both the attribute selector:

selector: '[myHighlight]',

and an input property:

@Input('myHighlight') highlightColor: string;

I find it odd/counterintuitive that we don't have to specify the selector attribute like this (although if we do write it this way, it still works):

<span myHighlight [myHighlight]="color">highlight me</span>

Instead, we only have to specify the input property, and we magically get the directive as well:

<span [myHighlight]="color">highlight me</span>

I don't like this "shortcut"/syntactic sugar/magic, since it looks like we're binding to the myHighlight property of the span element, rather than what is actually happening: we're binding to the myHighlight property of the myHighlight attribute directive. So, just by looking at the HTML, we can't easily determine which element/component/directive the myHighlight property is bound to.

Why does it work this way?

Consider this HTML fragment:

<div [accessKey]="...">

Is accessKey an HTML element property or an attribute directive with an input property also named accessKey? (FYI, accessKey is a valid HTML element property, so this example is not an attribute directive.)

Getting back to the highlight directive... if I change the input property name to highlightColor:

@Input() highlightColor: string;

Then I have to specify the attribute selector along with the property binding, which I find less ambiguous:

<span myHighlight [highlightColor]="color">highlight me</span>

So the "shortcut" only seems to work if the input property name matches the attribute selector.

Update: it seems structural directives use the same trick/shortcut. E.g.,

<p *ngIf="condition">
  text here
</p>

is equivalent to

<template [ngIf]="condition">  <--- binds input property ngIf to NgIf directive, not to template
  <p>
    text here
  </p>
</template>

I just don't like the mixing of property name and selector.

like image 229
Mark Rajcok Avatar asked Dec 22 '15 19:12

Mark Rajcok


1 Answers

At ng-conf 2016, I talked to Alex Rickabaugh, one of the Angular team members, about my concerns. He pointed out that the syntax is ambiguous in other ways as well. E.g., we discussed this syntax:

<my-comp [whatIsThis]="someProperty">

We can't tell from reading the HTML if whatIsThis is a directive with an input property of the same name, or if whatIsThis is an input property of the my-comp component.

I guess the bottom line is that with Angular 2 we can't simply look at the HTML to understand what kind of binding is happening. We have to know about the directives and components the application uses. Bummer.

like image 75
Mark Rajcok Avatar answered Sep 28 '22 18:09

Mark Rajcok