1

How does Angular 2 differentiate if we are using [] token for setting attribute or attribute directive? They both look the same.

For example:

<div [count]="counter"></div>
<div [ngClass]="setClasses()"></div>

Does it check for directive first and if not present then interprets it as attribute assignment? I am confused.

I mean what if we have a attribute named "value" and directive named "value". How does Angular2 handle this?

Narayan Prusty
  • 2,501
  • 3
  • 22
  • 41

2 Answers2

1

At first its important to understand the difference between property and attribute.

See
- Properties and Attributes in HTML

If angular doesn't find an @Input() on a directive or component and also not a native property it throws - Can't bind to 'for' since it isn't a known native property angular2

Angular has different binding syntax for attribute and property binding

[count]=... and [ngClass]=... are property bindings.
Attribute bindings are either - count="someString" - attr.count="{{someProperty}}" or - [attr.count]="someProperty".

Community
  • 1
  • 1
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • so you mean Angular2 first checks if there is such kind of directive present or not. If not then it takes it as an attribute. Right? – Narayan Prusty Apr 26 '16 at 19:43
  • Actually `[count]` and `[ngClass]` are property bindings. Attribute bindings are either `count="someString"` or `attr.count="{{someProperty}}" or `[attr.count]="someProperty"`. Properties of native DOM elements can be set the same way though. – Günter Zöchbauer Apr 26 '16 at 19:46
  • If an element has a native property (not attribute, they are often reflected from one to the other tough) Angular sets it as well when property binding syntax is used. So, yes, Angular checks for directives and components and also for native properties and assigns the value to what it finds. – Günter Zöchbauer Apr 26 '16 at 19:49
  • In [this](https://angular.io/docs/ts/latest/guide/attribute-directives.html) article under 'Why not call it "highlight"?' tip it clears the confusion. So the answer is that first it checks to see if it is a built in directive, then custom directive and if not then assumes it to be element attribute. – Narayan Prusty Apr 26 '16 at 19:49
  • That's not entirely true. If there is no directive or component that has an input or property with that name it tries for a property. If there is no such property it throws. For attributes the it requires explicit attribute binding syntax. See for example http://stackoverflow.com/questions/35229960/cant-bind-to-for-since-it-isnt-a-known-native-property-angular2/35230069#35230069 and http://stackoverflow.com/questions/6003819/properties-and-attributes-in-html – Günter Zöchbauer Apr 26 '16 at 19:52
  • The last statement about attributes is wrong. `count="someString"` is **not** an attribute binding. In fact, the only way to bind an attribute in Angular2 is with `attr.count="{{someProperty}}"` ([Doc](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#binding-targets)). People should not get hung up on the `[ ]` on the left hand side, as it does not affect semantics of **what** is targeted in any way. Here, it's always some kind of property. – Insa May 09 '17 at 17:45
  • (sry, had to split the comment) The difference between `[]` and no parenthesis is whether a property is bound or set once by interpolation (evaluating an expression) (Section: _Property binding or interpolation?_ [Doc](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#property-binding-or-interpolation)) – Insa May 09 '17 at 17:46
  • `count="someString"` is plain HTML and not related to Angular and it is valid when `someString` is a literal string (not a field reference) and creates the attribute `count="someString"`. – Günter Zöchbauer May 09 '17 at 17:47
  • Not sure what you mean by "People should not get hung up on the [ ] on the left hand side". `[]` on the left hand side is to allow to bind other value types than string. For attributes that doesn't matter because attributes can only hold string values, therefore the bound value will be stringified. With `{{}}` the value will always be stringified, no matter if you bind to an attribute or property. – Günter Zöchbauer May 09 '17 at 17:50
0

The target name is always the name of a property, even when it appears to be the name of something else. Element properties may be the more common targets, but Angular looks first to see if the name is a property of a known directive.
Technically, Angular is matching the name to a directive input, one of the property names listed in the directive’s inputs array or a property decorated with @Input(). Such inputs map to the directive’s own properties.

Above from the Template Syntax doc, section Binding target.


See also Why does simply [myHighlight]="..." work for an attribute directive?, where I ask why we don't have to write <div ngClass [ngClass]="...">.

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492