Data binding

Aurelia has its own data binding system. Let's explain that with an example.

You know that you need to define a view and a view model file for each Aurelia component. Binding is the process that reflects the view model data into the view, and vice versa. As we said earlier, one of Aurelia's most beautiful features is double-binding framework, so you won't have to worry about updating the data on the view or view model.

Aurelia supports HTML and SVG attributes to JavaScript expressions. The binding attribute declaration is composed of three parts:

attribute.commamnd = "expression"

Let's explain each one:

attribute: Refers to the HTML/SVG attribute we will apply to the binding. For example, one input tag could have defined the following attributes:

<input  value="someValue" id="inputId"  />

value and id will be the attributes we could refer.

command: Here, you will use one of Aurelia's binding commands:

  • one-time: Flows data to one direction, from view model to view, just once.
  • to-view one-way: Flows data in one direction, from view model to view.
  • from-view: Flows data in one direction, from view to view model.
  • two-way: Default behavior, flows data from view model to view and vice versa.
  • bind: Automatically chooses the binding mode. It uses two-way binding for form controls and to-view binding for almost everything else.

Let's use the same input element defined earlier as an example:

<input  value.from-view="userInputValue" id.bind="editableId"  />
<input value.one-time="defaultInputValue" id.one-way="generatedId" />

The first input element uses the from-view command to bind anything the user writes in the input element, but this value cannot be changed and reflected from the view-model into the view. The id attribute uses the two-way binding, so this id can be updated in the view layer and reflected in the view model. The second binds the value attribute just once, then any update to this value will be ignored. In the case of the id attribute, it is generated by the view-model file, and any modification from view won't be reflected on view-model.

expression: The last part. Commonly a JavaScript expression used to reflect view-model attributes, computed properties, and so on. Again, let's use the same input element for example purposes:

<input  value.from-view="modelValue" id.bind="formName + randomNumber"  />

The value attribute just reflects the modelValue property into the view. The id attribute is performing an operation to attach a random number generated in the view model into one predefined property and use it as a single value to bind.

The same way that as event managing part, there could be some situations that you will need to use a little more advanced features to get the expected results. Commonly, you may deal with situations where you have @bindable properties while developing custom elements/attributes. These properties expect a reference to a function, so just use the call binding command to declare and pass a function to the bindable property. The call command is superior to the bind command for this use case, because it will execute the function in the correct context, ensuring that this is what you expect it to be:

  <custom-element go.call="doSomething()"></custom-element>

go is the @bindable attribute, and doSomething() is your view-model function.

One more feature you can add to your application is string interpolation. These expressions enable interpolating the result of an expression with text. The best way to demonstrate this capability is with an example. Here are two span elements with data-bound textcontent:

    <span textcontent.bind="'Hello' + name"></span>

    <span>Hello ${name}</span>

At this point, we know the basic concepts about Aurelia's binding engine. Now, let's use this great feature in more advanced ways to improve our application!

We have explored in Chapter 2Styling the User Interface, some ways to add CSS to our application and make it look great. However, in your daily work, you can find some common situation that will make you 'mix' some features.

Here's one:

You are writing a dashboard page and depending on user status (active, inactive), the Submit button should look colorful or just disabled with a different shape.

You can bind an element's class attribute using string interpolation or with .bind/.one-time:

<template>
<button class="btn ${isActive ? 'btn-active' : 'blocked-btn'} submit"></button>
<button class.bind="isActive ? 'btn-active' : 'blocked-btn'"></button>
<button class.one-time="isActive ? 'btn-active' : 'blocked-btn'"></button>
</template>

Using ternary operations, you can say to your view which class should be rendered into the view. Let's analyze the first:

  • isActive refers to a boolean property defined in view model.
  • ? is the ternary operator. If the condition is true, the first argument will be used, in this case, the 'btn-active' class.
  • : represents the else element of the condition. If it's evaluated to false, the second argument after the : will be used.

Aurelia allows you to use external JavaScript libraries. It supports, on its binding system, only adding or removing the specified classes in the binding expression.

In this way, classes added by other code (for example, classList.add(...)) are not removed. This behavior implies a small cost, noticeable only in benchmarks or some critical situations like iteration of large lists. Replace the default behavior by binding directly to the element's className property using class-name.bind="....", or class-name.one-time="..." can be a better option; so much faster.

Similar to classes, you can bind style attributes directly into the DOM. Remember that defining styles directly into the element is not wrong, but using classes, you can add more standardization to your elements and make this easy to maintain. Like other HTML attributes, you can use style.bind to retrieve style definitions from your view-model.

For example, let's define one array of styles:

export class StyleExample {
constructor() {
this.styleAsString = 'color: red; background-color: blue';

this.styleAsObject = {
color: 'red',
'background-color': 'blue'
};
}
}

Then, in the view file, we just need to bind the predefined properties:

<template>
      <div style.bind="styleAsString"></div>
      <div style.bind="styleAsObject"></div>
</template>

You can use string interpolation too:

<div style="width: ${width}px; height: ${height}px;"></div>

However, if you need to add compatibility with Internet Explorer and Edge, this syntax will be illegal. In those cases, you must use the css attribute:

<div css="width: ${width}px; height: ${height}px;"></div>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset