Combine Views with Aurelia

In my contacts sample application, I wanted to combine the list and detail views for a better user experience. Turns out that Aurelia’s contact sample application does this and a few other things I want to try out in the future so I used it as a guide.

Starting with the my app.html with the nav related markup.

<template>
    <require from="lib/bootstrap/dist/css/bootstrap.css"></require>
    <require from="Aurelia/list" as="contact-list"></require>

    <div class="page-host">
        <contact-list class="col-md-4"></contact-list>
        <router-view class="col-md-8"></router-view>
    </div>
</template>

The require statement tells Aurelia to load the specified resource. The as attribute of require is optional and defines how the imported resource will be accessed. By using the as attribute what would have been a list custom element is now a contact-list custom element.

The other change to this file was to render the contact-list element in addition to the router-view. Columns classes were assigned to both since they will be sharing view space now.

In app.js the configuration of the routes had to be adjusted. Before the blank route rendered the list view, but now the list view is rendered outside of the router so the detail route needed to be rendered for the blank route. The original route with an id still exists and is used to load the proper details when an item is selected from the contact list.

export class App {
    configureRouter(config, router) {
        config.title = 'Contacts';
        config.map([
            {
                route: ['', 'detail/:id'],
                name: 'detail',
                moduleId: './Aurelia/detail',
                nav: false,
                title: 'Detail'
            }
        ]);

        this.router = router;
    }
}

After the above changes I tried a test and got a detail view but no list view. After some digging I found out that the activate function was not being called on the list class. Turns out that since list view is being rendered outside of a router that the activate portion of the lifecycle does not happen. Since activate is where I was hitting my ASP.NET 5 web api no contacts were being loaded. The fix was to use the created portion of the lifecycle instead of activate.

created(){
    return this.http.fetch('contacts')
       .then(response => response.json())
       .then(contacts => this.contacts = contacts);
}

After that change all worked as I hoped it would. This is just a basic example of what is a very powerful concept. The more I learn about Aurelia the more I like it.

Leave a Comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.