简体   繁体   中英

How to override Aurelia ViewModel resolution?

The Aurelia framework has a strong appeal to convention-over-configuration.

In its docs sample app (typescript) , we've got a source code structure like this:

.
├── index.html
├── config.js
├── src
    ├── main.ts
    ├── app.ts         // viewmodel
    ├── app.html       // view
    ├── welcome.ts     // viewmodel
    ├── welcome.html   // view
    ├── users.ts       // viewmodel
    ├── users.html     // view
    (...)

For organization purposes, I would rather organize the sources with each view/viewmodel/private components/etc in their own folder, obtaining a folder structure like this:

.
├── index.html
├── config.js
├── src
    ├── main.ts
    ├── app
        ├── app.ts            // viewmodel
        ├── app.html          // view
    ├── welcome
        ├── welcome.ts        // viewmodel
        ├── welcome.html      // view
    ├── users
        ├── users.ts          // viewmodel
        ├── user-info.ts      // view-specific component (1)
        ├── user-detail.ts    // view-specific component (2)
        ├── users.html        // view
    (...)

Is there a way to do this implementing a custom resolver or overriding the convention? That is, I want to avoid explicit path boilerplate code in my Router config. Any suggestions?

There's a workaround.

I see that you don't want to type the specific path all the time, like: welcome/welcome . So, you can put the routes array in a variable, and then replace all moduleIds, according to your pattern. Like this:

let routes = [
    { route: ['', 'welcome'], name: 'welcome', moduleId: 'welcome', nav: true, title: 'Welcome' },
    { route: 'test', name: 'test', moduleId: 'test', nav: true, title: 'Test' },
 ];

updateRoutes(routes);

config.map(routes);

Update routes function:

 function updateRoutes(routes) {
     for (i = 0; i < routes.length; i++) {
        let route = routes[i];
        if (route.moduleId.indexOf('/') === -1) {
            route.moduleId = `${route.moduleId}/${route.moduleId}`;
            routes[i] = route;
        }
     }
 }

So, welcome becomes welcome/welcome . Be aware that the function will only replace the moduleId if there's no '/' in its value;

Using this way, you aren't "hurting" the framework, as explained in the @JeremyDanyow's comment.

In main.js , .setRoot() becomes .setRoot('app/app') . This is required because setRoot with no args assumes an app.js at the root of your project.

Route configuration changes are limited to the moduleId ... This:

config.map([
  { route: ['', 'welcome'], name: 'welcome',      moduleId: 'welcome',      nav: true, title: 'Welcome' },
  { route: 'users',         name: 'users',        moduleId: 'users',        nav: true, title: 'Github Users' },
]);

Becomes this:

config.map([
  { route: ['', 'welcome'], name: 'welcome',      moduleId: 'welcome/welcome',    nav: true, title: 'Welcome' },
  { route: 'users',         name: 'users',        moduleId: 'users/users',        nav: true, title: 'Github Users' },
]);

Not sure if this answers your question. Are you looking for a way for the router to convert the moduleId from 'welcome' to 'welcome/welcome' ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM