Routing names with ember.js - ember.js

I have a router like this
App.Router.map(function () {
this.route("about");
this.resource("invoices", { path: "/invoices" }, function () {
this.resource("invoices.show", { path: "/:id" });
this.resource("invoices.update", { path: "/:id/edit" });
this.route("create");
});
});
and to generate links to the various routes and resources I have this
<nav>
{{#linkTo "invoices.index"}}Invoices{{/linkTo}}
{{#linkTo "invoices.show" 1}}Invoice{{/linkTo}}
{{#linkTo "invoices.create"}}New invoice{{/linkTo}}
</nav>
Why do I have to use invoices.show for the name of the show resource and then reference it as invoices.show but I can use create for the route and then reference it as invoices.create?
Ideally my router would be
App.Router.map(function () {
this.route("about");
this.resource("invoices", { path: "/invoices" }, function () {
this.resource("show", { path: "/:id" });
this.resource("update", { path: "/:id/edit" });
this.route("create");
});
});
and it would auto-prefix the resource names since they are nested within the invoices resource. Right?

Yes, the nested resources can stack their names, and you should be able to reference a nested route with dot notation.
However, you will want to do something more like:
this.resource("invoices", { path: "/invoices" }, function () {
// invoices.show
this.resource("show", { path: "/:id" }, function() {
// invoices.show.update
this.route("update", { path: "/edit" });
});
// invoices.create
this.route("create");
});
since your update operation relies on the object supplied to the show route.
Basically nested elements that rely on the same, or a subset of resources used in a parent route should be defined as resource mappings. Leaf nodes can be defined as basic routes.

Related

Ember JS - routing from resourse to route

i'm trying to update and ember project from version 2.x to version 3.x, and one of my first issue is that in the route file i get this.resouce is not defined. i belive this was deprecated. the code looks like this :
this.route('objects', function () {
this.route('search', { path: '/' }, function () {
this.resource('objects.items', { path: '/:search_id' }, function () {
this.resource('objects.item', { path: '/item/:item_id'}, function () {
this.route('general', { path: '/' });
this.route('tab', { path: '/tab/:tab' });
this.route('relations');
this.route('diagram');
this.route('comments');
this.route('sources');
this.route('views');
});
});
});
});
i've tried to simply change the resource to route and give resetNameSpace: true attribute, but didn't help. also i've tried various combinations, but without luck.
anyone with experience can help me redo this routing to be compatible with the latest ember?
As this.resource() is actually an old Ember way of resetting the namespace, the resetNameSpace: true attribute does indeed do the same!
Because you used this.resource('objects.items'), you actually created a resetted namespace where objects was the route.
So your new router would look something like¹:
this.route('objects', function () {
this.route('search', { path: '/'});
this.route('items', { path: '/:search_id'});
this.route('item', { path: '/item/:item_id' }, function () {
this.route('general', { path: '/' });
this.route('tab', { path: '/tab/:tab' });
this.route('relations');
this.route('diagram');
this.route('comments');
this.route('sources');
this.route('views');
});
});
This way you could still use transitionToRoute("objects.item.general", id).
¹ Notice no resetNameSpace flag is used!

Dynamic segments for nested ember routes not working

I have a nested route structure:
//router.js
this.route('maps', { path: '/maps' }, function () {
this.route('show', { path: '/:id' }, function () {
this.route('display', { path: '/display' }),
this.route('layers', function () {
this.route('create')
})
});
});
my understanding here is that I should have a route maps.show.display that should take a single dynamic segment like maps/1/display
However when I go to transition or link to this ie:
//maps route
afterModel: function (resolvedModel) {
var newestFlight = resolvedModel.content[0];
var newestMap = newestFlight.get('map');
this.transitionTo('maps.show.display', newestMap);
}
or
{{#link-to 'maps.show.display' id}}show map{{/link-to}}
I get an error:
Error while processing route: maps.index More context objects were passed than there are dynamic segments for the route: maps.show.index
It makes it even weirder that this route accepted the same dynamic segment when it was just maps/display so I don't understand why nesting it further breaks it.
Any ideas as to what I'm doing wrong would be greatly appreciated
edit: interestingly, this awesome tool
also seems to agree that I should have a dynamic segment here if you post my route in there
It works fine for me: http://emberjs.jsbin.com/rofowuneni/1/edit?html,css,js,output
BTW I think this:
this.route('display', { path: '/display' });
this.route('layers', function () {
this.route('create')
});
Is supposed to be (not that it matters):
this.route('display', { path: '/display' });
this.route('layers', function () {
this.route('create');
});
What's your ember version?

Ember.js: there is no route named 'new-table'

Here are my routes definition:
Router.map(function() {
this.resource('servers', { path: '/' }, function() {
this.resource('server', { path: '/servers/:serverid'}, function () {
this.resource('databases', { path: '/databases' }, function () {
this.resource('database', { path: '/:databaseid'}, function () {
this.resource('catalogues', { path: '/catalogues' });
this.resource('eventtriggers', { path: '/eventtriggers' });
this.resource('extensions', { path: '/extensions' });
this.resource('schemas', { path: '/schemas' }, function () {
this.resource('schema', { path: '/:schemaid' }, function () {
this.resource('tables', { path: '/tables' }, function () {
this.route('new-table', function () {});
this.resource('table', { path: '/:tableid' });
});
});
});
this.resource('replication', { path: '/replication' });
});
});
});
});
});
And the code used to generate link to new-table route goes as follows:
{{#link-to 'new-table' schema.database.server.id schema.database.id schema.id}}
And this gives me the error mentioned in this question's topic. However when I replace this.route call to this.resource everything works fine. So what am I doing wrong here? I'm using ember 1.13.2.
A resource defines the main entry point of a link-to. So if you create a resource new-table you can access it via new-table in the link-to helper. Routes on the other hand are children of a resource or another route, they should be prefixed with their parent route or resource. So in the example you gave, you can link to the new-table route by using tables.new-table.

Adding a new route to an existing Ember.js app, need input

I have an existing Ember app which works great. I need to add a new subroute to the app to allow users to view additional information. My current route looks like this:
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'});
});
});
with the following URL
#/accounts/56/
The route I'd like to add is this:
#/accounts/56/interactions
So I added a nested route like so:
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: '/interactions'});
});
});
});
But when that route is accessed I get the following error:
Uncaught Error: assertion failed: The route interactions was not found core.libs.js:2236
Uncaught Error: You cannot modify child views while in the inBuffer state core.libs.js:19298
So I also added an empty InteractionsRoute but that didn't resolve it:
Social.InteractionsRoute = Ember.Route.extend();
Does anyone have input on what might be going wrong?
In addition I'm trying to add a button to the interface which looks like this:
{{#linkTo "interactions"}}# Interactions{{/linkTo}}
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: '/interactions'});
});
});
});
Like this the URL to interactions is #/interactions
But you wanted this: #/accounts/56/interactions
Therefore you need to remove the preceding slash in the path hook of interactions, otherwise you'll indicate that this route will be accessed from the root.
Social.Router.map(function() {
this.resource('accounts', { path: '/accounts' }, function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions', { path: 'interactions'});
});
});
});
By the way, if you don't declare a path hook the url will be the same as the route name. So you can also use this:
Social.Router.map(function() {
this.resource('accounts', function(){
this.resource('account', { path: ':account_id'}, function(){
this.route('interactions');
});
});
});
Try splitting out your list from the individual record view.
Social.Router.map(function() {
this.resource('accounts');
this.resource('account', { path: '/accounts/:account_id' }, function() {
this.route('interactions');
});
});
Your route name for interactions should be like this:
Social.AccountInteractionsRoute = Ember.Route.extend();
From the table on http://emberjs.com/guides/routing/defining-your-routes/
If all else fails you could just avoid the nested resources and define the paths for each route.
Social.Router.map(function() {
this.resource('accounts');
this.resource('account', { path: '/accounts/:account_id' });
this.resource('account-interactions', { path: '/accounts/:account_id/interactions' });
});

Ember.js pass params object to linkTo or action helper

Is there a way to pass a params object to a linTo or action helper?
I have an object and it needs compound keys. I am using Ember Model and had to modify the adapter. In the Router that gets the initial object i pass a params object with the necessary keys. My problem is trying to do the same thing when using either a linkTo or action with a transitionToRoute. Neither hit the router again as far as I can tell.
Im coming back to this questions. Im still not sure the proper way to handle this.
App.Router.map(function () {
this.resource("clients", { path: 'clients' }, function () {
this.resource("client", { path: ':client_id' }, function () {
this.resource("claims", function () {
this.resource('claim', { path: ':claim_id/:claim_sub' }, function () {
this.resource('lines', { path: 'lines' }, function () {
this.resource('line', { path: ':line_id' }, function () {
this.resource('flags', function () {
this.resource('flag', { path: ':flag_id' });
});
});
this.route('claim_lines');
});
});
});
});
});
this.route("errors", { path: '/errors/:error_id' });
});
When i link to anything under the claim, where the compound slugs are, i get those set to undefined.
UPDATE
The serialize was just what i needed.
App.ClaimRoute = Nucleus.Route.extend({
model: function (params) {
params.client_id = this.modelFor('client').get('client_id');
return App.Claim.find('claim', params);
},
serialize: function (model) {
return { claim_id: model.get('cla_seq'), claim_sub: model.get('cla_sub') };
}
});
I think a code example will be most helpful, but to try to answer your question, yes you can pass an object to linkTo with something like the following:
{{#linkTo routename params}}Text for Link{{/linkTo}}
Then for the route code matching the route name, you can take params as a parameter when you define the serialize function and use them to build the URL to match the routing segments defined in your router:
serialize: function(params) {
// params.property1 and params.property2
return { segment_1: params.property1, segment_2: params.property2 };
}