Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember-CLI Routing: Changed my route/template structure, but build does not recognize the changes?

I just now, changed my route structure within ember-cli and broke my app. I wanted to nest my current structure one level deeper...

Before:

Router.map(function() {
    this.resource('placements', function() {
        this.route('add');
        this.route('import');
        this.route('open');
    });
    this.route('admin');
});

After:

Router.map(function() {
    this.resource('portal', function() {
        this.resource('placements', function() {
            this.route('add');
            this.route('import');
            this.route('open');
        });
        this.route('admin');
    });
});

My Template structure also needed to change...

Before:

- templates/
-     placements/
-         add.hbs
-         import.hbs
-         index.hbs
-         open.hbs
-     admin.hbs
-     application.hbs
-     index.hbs
-     placements.hbs

After:

- templates/
-     portal/
-         placements/
-             add.hbs
-             import.hbs
-             index.hbs
-             open.hbs
-         admin.hbs
-         index.hbs
-         placements.hbs
-     application.hbs
-     index.hbs
-     portal.hbs

I thought I have made all the changes 1-to-1 but for some reason when I relaunched ember server, the nested "placements" routes are broken.

In the console log, I noticed that ember is still trying to look for the placements.index under the old templates/placements/index rather than the new directory.

There is one theory that templates can't be nested in the same way that the router can? That implies that I might need to explicitly define each route with a renderTemplate hook in order for it to display the correct template... this can be a pain because this project is going to be pretty large... perhaps there is something else that I am doing wrong?

like image 356
Grapho Avatar asked Jan 11 '23 07:01

Grapho


1 Answers

After working on the comments @Adam left me. I was able to figure out the correct way to work with the templates.

Templates, indeed do not nest in exactly the same pattern that resource/routes do.

Given the new route structure I made:

Router.map(function() {
    this.resource('portal', function() {
        this.resource('placements', function() {
            this.route('add');
            this.route('import');
            this.route('open');
        });
        this.route('admin');
    });
});

The templates should be structured like so:

- templates/
-     placements/
-         add.hbs
-         import.hbs
-         index.hbs
-         open.hbs
-     portal/
-         admin.hbs
-         index.hbs
-     application.hbs
-     index.hbs
-     placements.hbs
-     portal.hbs

When you define a "resource", that essentially causes that particular route to be a top level object, regardless of how deeply nested it appears in the router map. placements.hbs and portal.hbs (from above) are "resource" (top level) templates and are placed in the top level of the templates directory accordingly.

Since those two "resource" templates each have an {{outlet}} the "children" route templates need to be placed within a top level directory which is named after its corresponding resource.

The Ember-CLI docs describe this pattern only showing an example one level deep, so I first assumed that the pattern repeated going in deeper. I hope this helps clarify the actual way to go for anyone else that is learning Ember.


Update:

As of EMBER 1.7.0

Routes are now nestable!

This is exciting news for me personally, but it merits an update to this answer.

Resources are still usable as the example above, so if you are comfortable with that, you can keep going that way for a while. But keep in mind, Resources are planned for an eventual path to deprecation. Eventually, there will only be routes and nested routes.

The good news is that, if you follow the new pattern, you can nest your templates more naturally to match your router structure, just like a natural REST style app should be. No more awkward mental mapping.

For instance this same router from above (with the slight change):

Router.map(function() {
    this.route('portal', function() {
        this.route('placements', function() {
            this.route('add');
            this.route('import');
            this.route('open');
        });
        this.route('admin');
    });
});

The templates can be structured like so:

- templates/
-     portal/
-         placements/
-             add.hbs
-             import.hbs
-             index.hbs
-             open.hbs
-         admin.hbs
-         index.hbs
-         placements.hbs
-     application.hbs
-     index.hbs
-     portal.hbs

The same pattern applies to nesting the corresponding /routes, /controllers, /adapters, etc., etc.

This also means (with this new pattern) {{link-to}} helpers and transitionTo methods will need to include the full path of a route: e.g. {{link-to 'portal.placements.index'}}.

like image 53
Grapho Avatar answered May 03 '23 23:05

Grapho