Building  Large-Scale Web Applications with Angular
上QQ阅读APP看书,第一时间看更新

Attribute binding

The only reason attribute binding exists in Angular is that there are HTML attributes that do not have a backing DOM property. The colspan and aria attributes are some good examples of attributes without backing properties. The progress bar div in our view uses attribute binding.

If attribute directives are still playing your head, I cannot blame you, it can become a bit confusing. Fundamentally, they are different. Attribute directives (such as [ngStyle]) change the appearance or behavior of DOM elements and as the name suggests are directives. There is no attribute or property named ngStyle on any HTML element. Attribute binding, on the other hand, is all about binding to HTML attributes that do not have backing for a DOM property.

The 7 Minute Workout uses attribute binding at two places, [attr.aria-valuenow] and [attr.aria-valuemax]. We may ask a question: can we use standard interpolation syntax to set an attribute? No, that does not work! Let's try it: open workout-runner.component.html and replace the two aria attributes attr.aria-valuenow and attr.aria-valuemax enclosed in [] with this highlighted code:

<div class="progress-bar" role="progressbar"  
    aria-valuenow = "{{exerciseRunningDuration}}"  
    aria-valuemin="0"  
    aria-valuemax= "{{currentExercise.duration}}"  ...> </div> 

Save the view and if the app is not running, run it. This error will pop up in the browser console:

Can't bind to 'ariaValuenow' since it isn't a known native property in WorkoutRunnerComponent ... 

Angular is trying to search for a property called ariaValuenow in the div that does not exist! Remember, interpolations are actually property bindings.

We hope that this gets the point across: to bind to an HTML attribute, use attribute binding.

Angular binds to properties by default and not to attributes.

To support attribute binding, Angular uses a prefix notation, attr, within []. An attribute binding looks as follows:

[attr.attribute-name]="expression" 

Revert to the original aria setup to make attribute binding work:

<div ... [attr.aria-valuenow]="exerciseRunningDuration" 
[attr.aria-valuemax]="currentExercise.duration" ...>
Remember that unless an explicit attr. prefix is attached, attribute binding does not work.

While we have not used style and class-based binding in our workout view, these are some binding capabilities that can come in handy. Hence, they are worth exploring.