How do I use dynamic segments in EmberJS' 2.2

2020-05-28 11:08发布

问题:

I can't figure out how to create routes with dynamic segments in the new router API for EmberJS. I've spent a week on it and tried many things but it doesn't work. I am really frustrated at myself because I've gone through the docs, API and source code many times and cannot figure out how to make this work. I am dying for assistance.

I am trying to achieve the following routes:

  • /profile/:userId -> index
  • /profile/:userId/activity -> activity page
  • /profile/:userId/...

My router is set up like this

App.Router.map(function() {
  return this.resource("profile", function() {
    this.route("index", { path: '/:userId' });
    this.route("activity", { path: '/:userId/activity' });
  });
});

Then, whenever I try to link with the linkTo helper, I receive the following error: Uncaught More objects were passed than dynamic segments

<li>{{#linkTo "profile.index" user}}overview{{/linkTo}}</li>

If I don't include the user object, then I receive another error Uncaught Error: assertion failed: Cannot call get with 'id' on an undefined object. (obviously because there's no object to take the ID of)

If it's any helper, here are my route declarations

App.ProfileIndexRoute = Ember.Route.extend({
  model: function(params) {
    return Ember.Object.create({
      id: 1
    });
  },
  setupController: function(controller, model) {
    return controller.set("content", model);
  }
});

App.ProfileActivityRoute = Ember.Route.extend({
  model: function(params) {
    return Ember.Object.create({
      id: 1
    });
  },
  setupController: function(controller, model) {
    return controller.set("content", model);
  }
});

回答1:

JSBin example

You can structure your routes with a little bit more nesting to get the URLs you desire (and you don't need to have a return statement in your router):

App.Router.map(function() {
  this.resource("profile", function() {
    this.resource("userprofile", { path: '/:userId' }, function() {
      this.route("index", { path: '/' });
      this.route("activity", { path: '/activity' });
    });
  });
});

and then set up your routes like this:

App.IndexRoute = Ember.Route.extend({
  model: function(params) {
    return [Ember.Object.create({
      id: 1
    })];
   }
});

App.UserprofileIndexRoute = Ember.Route.extend({
  model: function(params) {
    console.log("userindex route", params);
    return Ember.Object.create({
      id: 1
    });
  },
  setupController: function(controller, model) {
    return controller.set("content", model);
  }
});

App.UserprofileActivityRoute = Ember.Route.extend({
  model: function(params) {
    return Ember.Object.create({
      id: 1
    });
  },
  setupController: function(controller, model) {
    return controller.set("content", model);
  }
});

You can link to the /profile/1 page:

{{#linkTo userprofile.index user}}

or link to the /profile/1/activity page:

{{#linkTo userprofile.activity user}}