emberjs using multiple paths / urls for one route

2019-04-23 23:38发布

问题:

In Ember I can use this:

App.Router.map(function() {
    this.route('accomodations');
});

so if one goes to /accomodations it will load that view.

I can also add:

App.Router.map(function() {
    this.route('accomodations', { path: '/travel' });
});

so if one goes to /travel, it will go to the same view.

I want to be able to have /accomodations and /travel go to the same view? is this possible?

I know that this:

App.Router.map(function() {
    this.route('accomodations');
    this.route('accomodations', { path: '/travel' });
});

Will do what I'm asking, but if they go to accommodations, it should show that in the url, it always shows travel. I'm not even sure if the final piece of code is best practice.

回答1:

Using redirection

In router.js

App.Router.map(function() {
    this.route('accomodations');
    this.route('travel');
});

In routes/travel.js

App.TravelRoute = Ember.Route.extend({
    redirect: function() {
        this.transitionTo('accomodations');
    },
});

You do not have to put these in separate files (that's just where I would put them).

What this does is register two routes with the router. Pick one of them to be the "main" route, and the other the "alias" route. In this case, accomodation is the main route, and travel is its alias. When the user visits /travel, they get redirected to /accomodation.

This would be the default/ standard Ember way of accomplishing this, and if this sounds good to you, go for this.

Another possible solution

If you do not wish to have redirection happen, for some reason, and want the URL seen by the user to stay the same, but still display the same things, and behave in the same way, this is also possible.

In this case, you would create two of every single Ember unit (route, controller, view, template). The smart way would be to create a base class route, and have both App.TravelRoute and App.AccomodationRoute trivially extend it; create a base class controller, and have both App.TravelController and App.AccomodationController trivially extend it; same for views, if you have them.

Templates, OTOH, are a little trickier, because there is not way to extend them (that I know of). SO what you would need to do, is create either a partial or a component (decided which works better for you), and then reuse that partial/ component in both templates/accomodation.hbs and templates/travel.hbs



回答2:

You can simply interchange the two route-path definition lines:

App.Router.map(function() {

     this.route('accomodations', { path: '/travel' });
     this.route('accomodations');
});

The last definition takes the precedence for URL display in {{link-to ...'accomodations'}} and Route#transitionTo('accomodations') in-app transitions, though entering the app by '/travel' will leave the URL as is. (EmberJS 1.11.3, 2.12.2)