Value converters

As we explained before coming across this topic, user interface elements in Aurelia are composed of two files: view and view model pairs. The view is written in pure HTML and is rendered into the DOM. The view model is written in JavaScript and provides data and behavior to the view. Aurelia links the two files together, as one single element using its powerful data binding engine, allowing changes in your view model to be reflected in the view and vice versa. Sometimes the data showed by your view model is not in a good or understandable format for displaying in the UI. Dealing with date and numeric values are the most common scenarios:

export class Example {

constructor() {
this.showRawData();
}

showRawData() {
this.currentDate = new Date();
this.someNumber = Math.random() * 1000000000;
}

}

Our view should look like this:

<template>
      ${currentDate} <br/>
      ${someNumber}
</template>

This code will give us the current date and some random number; well, that's what we are expecting and that's okay, but let's see how this data is displayed:

Sun Dec 31 2017 18:04:45 GMT-0500 (-05)
936693540.3380567

That's definitely not friendly for user reading. A cool solution to this problem can be to compute the formatted values and expose them as properties of the view-model file. This is a valid approach, but remember that we are overloading our model with extra properties and methods; it can be a little messy in the future, especially when you need to keep the formatted values in sync when the original property value change. Fortunately, Aurelia has a feature to help us deal with these situations.

The most common option will be to create value converters to translate the model data into a readable format for the view. All okay at this point, but what happens if it is the view that needs to convert the value for sending it into a format acceptable for the view-model?

Aurelia value converters are quite similar to other value converters of another languages, such as XAML. The nice thing is that Aurelia comes with some notable improvements:

  • The Aurelia ValueConverter interface uses two methods: toView and fromView. These methods define the direction the data is flowing in.
  • Aurelia value converter methods can accept multiple parameters.
  • Aurelia allows you to use multiple value converters in one single property, just using pipes (|).

Let's look at an example to convert our date property into a more friendly readable value:

import moment from 'moment';

export class DateFormatValueConverter {

toView(value) {
return moment(value).format('M/D/YYYY h:mm:ss a');
}

}

Our view-model file won't change:

export class Example {

constructor() {
this.showRawData();
}

showRawData() {
this.currentDate = new Date();
this.someNumber = Math.random() * 1000000000;
}

}

However, our view-model file will look quite different at this time:

<template>
<require from="./date-format"></require>
${currentDate | dateFormat} <br/>
${someNumber}
</template>

With this value converter, we'll see this value on the screen:

12/31/2017 6:25:05 pm

This looks much better. Again, it's time to ask the more important question—why? Let's examine what we did. First, we created our value converter class called DateFormatValueConverter and implemented the toView method. Aurelia will execute this method and apply to the model values before displaying the data on screen. For converting purposes, we are using MomentJS. Next, we've updated the view file and added <require> tags to import our value converter class into the view that will use it.

When the framework processes the resource, it examines the class's metadata to determine the resource type (custom element, custom attribute, value converter, and such). Metadata isn't required, and in fact, our value converters didn't expose any. If you are curious, you must note something—we used the ValueConverter postfix to name our converter class. Again, why? It's because you must remember that one of the Aurelia bases is convention over configuration. In this way, the name ending with ValueConverter will be assumed to be one value converter.

Now we will show you a little more advanced example. Let's apply some changes to our class converter:

import moment from 'moment';

export class DateFormatValueConverter {

toView(value, format) {
return moment(value).format(format);
}

}

The view-model file is still the same. Now, our template file will change again:

<template>
      <require from="./date-format"></require>

      ${currentDate | dateFormat:'M/D/YYYY h:mm:ss a'} <br/>
      ${currentDate | dateFormat:'MMMM Mo YYYY'} <br/>
      ${currentDate | dateFormat:'h:mm:ss a'} <br/>
</template>

Now we can use the same value converter class to render data in different formats, according to our view demands.

Without any doubt, we have covered some of the most important features of Aurelia's binding behavior, but, for sure, there are more methods and commands that we will see in practice. For the moment, we are ready to pass to another important concept—routing.

..................Content has been hidden....................

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