yammerade
yammerade

Reputation: 629

How to use Aurelia's router with server-side routing

I have an Aurelia project that uses server-side routing with MVC. I am using a layout file that points to a main "app" component, like this:

<div aurelia-app="main" start="app" data-model='@Json.Encode( Model )'></div>

Each of my views contain a reference to the layout file and something like this:

<div aurelia-app="main" start="sample-module" data-model='@Json.Encode( Model )'></div>

My main.js is configured like this:

export function configure(aurelia) {
    aurelia.use.standardConfiguration()

    aurelia.container.registerInstance('viewModel', 
        Object.assign({}, JSON.parse(aurelia.host.dataset.model)));

    aurelia.start().then(a => {
        let start = a.host.attributes.start.value;
        a.setRoot(start);
    });
}

And I am leveraging Aurelia's router (in app.js) like this:

export class App {
    constructor() {
    }
    configureRouter(config, router) {

        config.title = 'Aurelia';

        config.options.pushState = true;
        config.options.root = '/';

        config.map([
            { route: ['', 'Aurelia/Home'],      name: 'home',          moduleId: 'home',              title: 'home',            nav: false },
            { route: 'Aurelia/SampleModule',    name: 'sample module', moduleId: 'sample-module',     title: 'sample module',   nav: true },
        ]);
        this.router = router;
    }
}

This almost works. If I navigate to SampleModule using the Aurelia navigation link, it loads the module but doesn't hit the server - doesn't even hit the View. If I navigate to Aurelia/SampleModule manually, it loads sample-module twice, including the data from the server. The Aurelia router updates the url exactly as I would expect, so if I navigate and then hit refresh it loads from the server correctly.

I want to be able to use the navigation to change the view without refreshing the entire page, but still leverage my server-side routing and hit the Views and Controllers.

Upvotes: 0

Views: 347

Answers (1)

yammerade
yammerade

Reputation: 629

I was able to solve my problem by removing the reference to the app from each of the views:

<div aurelia-app="main" start="sample-module" data-model='@Json.Encode( Model )'></div>

as well as removing the start logic from the layout file and main.js, so now my main.js looks something like this:

export function configure(aurelia) {
    aurelia.use.standardConfiguration()

    aurelia.container.registerInstance('viewModel', 
        Object.assign({}, JSON.parse(aurelia.host.dataset.model)));

    aurelia.start().then(() => aurelia.setRoot());
}

In the back end, the model has a unique property to each page:

public class AppViewModel
{
    public HomeViewModel Home { get; set; }
    public SampleModuleViewModel SampleModule { get; set; }
}

From the view model (i.e. sample-module.js), it checks to see if the associated property (AppViewModel.SampleModule) is populated, and if not, it makes an ajax call.

Upvotes: 0

Related Questions