How to namespace an ember route in Ember 1.11.0 - ember.js

My understanding is that Ember 1.11.0 deprecated resource in a router in favor of only using route. Per what I've read, the difference between the two was that a resource created a namespace. See: What is the difference between a route and resource in New Router API?
So the question is how do I namespace a route so that, in the example below, my comments Route, Controller, and View are not prefixed with 'Posts'?
App.Router.map(function() {
this.route("posts", { path: "/" }, function() {
this.route("new", { path: "/new" });
this.route("comments", { path: "/comments" }, function() {
this.route("new", { path: "/new" });
});
});
});

Try passing resetNamespace: true to the route like
this.route("comments", { path: "/comments", resetNamespace: true }, function() {
this.route("new", { path: "/new" });
});

You can use the resetNamespace option for a route, something like this:
this.route('posts', {}, function() {
this.route('comments', {resetNamespace: true});
});

Currently, there's no way of doing that using the public API without using this.resource, which is officially deprecated and slated for removal in Ember 2.0. Using resetNamespace is not officially supported as it is a private API so, technically, it may be removed at any time without warning.
The official solution to this problem is to refactor your application to accept that the Comments Routes and Templates are under Posts.

Related

Add a parent route in ember for existing routes

Here is my problem,
assume I am having an ember app with following ember route configuration:
Router.map(function() {
this.route('todos', function() {
this.route('new');
this.route('view', {
path: "/:id"
});
});
this.route('articles', function() {
this.route('view', {
path: "/:id"
});
this.route('new');
});
});
Now i want to add the add the prefix for each route based on some user information i would be fetching.
For eg:
Below are the two user information
dev = {
id: 1,
workspace: 'DEV'
}
qa = {
id: 2,
workspace:'TEST'
}
once the dev is landing in the app, route must be like:
todos:
/DEV/todos/new
and same for the other users.
once the qa is landing in the page, route must be like:
/TEST/todos/new
to solve this i know we generate the parent route and add all the other route as child, need to change the file structure for this case.
Here is Ember :
ember-cli: 2.13.3,
ember-data: 2.18.5
This is straight forward in Ember.js using the router's path as URL paths can be customized easily.
For your case, the todos route should have a dynamic segment (say, workplace) and hence, the router entry will be like:
Router.map(function() {
this.route('todos', { path: '/:workplace/todos' }, function() {
this.route('new');
...
});
});
And if you are transitioning to new todo page using this.transitionTo('todos.new', 'TEST'), then URL will be updated as TEST/todos/new.
This twiddle has a tiny demo. Hope that helps :)

How do I version a route in Ember properly?

I have an application where I would like to namespace a specific route. But I'm seeing that Ember renders the ancestor route (which is similarly named).
Details
Ember 1.12.0
Routes
this.resource('campaign', { path: ':campaign_id' }, function() {
// some more routes
});
this.resource('campaign_v2', { path: 'v2/:campaign_id' }, function() {
// new routes
});
Link in campaign template
{{link-to "Check out V2!" "campaign_v2" classNames="btn btn-primary"}}
Test
Expect: When visiting campaign.index and I click on "Check out V2!", I expect to be taken to campaign_v2.index
Result: I am taken to campaign_v2.index but campaign also renders
Here is the result in Ember Inspector:
However, if I reload the route, I get:
Don't use the resource helper and instead use the route helper. Also, you might consider using a route namespace (instead of the _v2 suffix).
Routes
this.route('campaign', { path: ':campaign_id' }, function() {
// more routes
});
this.route('v2', function() {
this.route('campaign', { path: ':campaign_id' }, function() {
});
You can then refer to the v1 and v2 route via: campaign and v2.campaign respectively.

Ember router naming conventions

I have a need for deep nesting some routes in ember, I have something like this.
this.resource('wizards', {
path: '/wizards'
}, function() {
this.resource('wizards.google', {
path: '/google'
}, function() {
this.resource('wizards.google.register', {
path: '/register'
}, function() {
this.route('step1');
this.route('step2');
this.route('step3');
this.route('summary');
});
});
});
What I was expecting was as structure like this:
url /wizards/google/register/step1
route name wizards.google.register.step1
route Wizards.Google.Register.Step1Route
Controller Wizards.Google.Register.Step1Controller
template wizards/google/register/step1
but I got this:
url /wizards/google/register/step1 //as expected
route name wizards.google.register.step1 //as expected
route WizardsGoogle.Register.Step1Route
Controller WizardsGoogle.Register.Step1Controller
template wizards/google.register.step1
What I don't get is when does ember stop using capitalization (WizardsGoogle) and start using namespaces (WizardsGoogle.Register). The seemingly inconsistency confuses me. I would have expected either of them.
I met the same things with deep nested resources. Although I didn't know how this happens, what I can tell is that you can always use CapitalizedNestedRoute without namespace, and Ember can recognize it. Although in Ember Inspector it displays "WizardsGoogle.Register.Step1Route".
In your example I defined such route:
App = Em.Application.create();
App.Router.map(function() {
this.resource('wizards', function() {
this.resource('wizards.google', function() {
this.resource('wizards.google.register', function() {
this.route('step1');
this.route('step2');
this.route('step3');
});
});
});
});
App.IndexRoute = Em.Route.extend({
beforeModel: function() {
// Transition to step1 route
this.transitionTo('wizards.google.register.step1');
}
});
App.WizardsGoogleRegisterStep1Route = Em.Route.extend({
model: function() {
// You can see this alert when you enter index page.
alert('a');
}
});
In this example the app will transition to WizardsGoogleRegisterStep1Route with no problem. And if you use container to find route like this:
App.__container__.lookup('route:wizards.google.register.step1').constructor
It will also display App.WizardsGoogleRegisterStep1Route. It's the same as Ember Guide describes. http://emberjs.com/guides/routing/defining-your-routes/#toc_nested-resources And Ember Guide doesn't introduce namespace route.
So I think it's better to according to what Ember Guide suggests (always use CapitalizedNestedRoute). And in my opinion it's easier to define CapitalizedNestedRoute than nested.namespace.route.
Finally, if you really want to use namespace route/controller/template, you can have a look at Ember.DefaultResolver. Check the API to learn how to extend it so container can lookup modules by your own rules.
Routes are "namespaced" inside resources. And resources uses what you call capitalization, where they sort of define a namespace (for routes to use).
So this set of routes:
App.Router.map(function() {
this.resource('posts', function() {
this.route('new');
this.route('old');
this.route('edit');
this.route('whatever');
});
});
Would result in routes with the following name:
PostsRoute
PostsNewRoute
PostsOldRoute
PostsEditRoute
PostsWhateverRoute
Whereas, the following set of routes:
App.Router.map(function() {
this.resource('posts', function() {
this.resource('photos');
this.resource('comments');
this.resource('likes');
this.resource('teets');
});
});
Would result in route with the following names:
PostsRoute
PhotosRoute
CommentsRoute
LikesRoute
TeetsRoute
Also note, that resources within resources don't get "namespaced" to the "parent" resource, so you'll always ever have the form:
{CapitalizedResourceName}Route // for resources
{CapitalizedParentResourceName}{RouteName}Route // for routes
I hope this helps you!

How to render into parent resource's index {{outlet}}

I have 2 nested resources, Post and Comment in an Ember router. I want this to reflect the url:
/posts/1/comments/1
Going to this page should,
Render the Post for id = 1 using post/index template.
Render the Comment for the Post with Comment id = 1 using the comment/index template
Here is the example on jsbin.
My routing code is,
App.Router.map(function() {
this.resource('home', { path: '/' });
this.resource('posts', { path: '/posts' }, function() {
this.resource('post', { path: ':post_id' }, function() {
this.resource('comments', { path: 'comments' }, function() {
this.resource('comment', { path: ':comment_id' }, function() {
// need explicit index
});
});
});
});
});
The templates and the rest of the Ember code is pretty much stock. Only thing different is I am redirecting to /posts/1/comments/1 from the home route.
I can't get the post or the comment to render inside the /index template. Both the Post body and Comment Body are blank.
It works if I embed the contents of the index template inside the main posts or comments template. But this isn't what I need, the comment needs to be nested inside the Post.
Any ideas how to get this working? Thanks.
PS: I am using ember-latest and ember-data latest.
Usually this sort of problem comes down to naming conventions. Probably ember is looking for controllers and templates that you do not expect. Try adding the following to your application then watch console, it will help you see what routes/controllers/templates are being used.
App = Ember.Application.create({
LOG_ACTIVE_GENERATION: true,
LOG_TRANSITIONS: true,
LOG_VIEW_LOOKUPS: true
});
Also, those routes are probably more complicated than they need to be. Typically it does not make sense for 'post' route to be nested within a 'posts' resource. Same goes for comment/comments. Try this instead:
App.Router.map(function() {
this.route('posts');
this.resource('post', { path: '/posts/:post_id' }, function() {
this.route('comments')
this.resource('comment', { path: '/comments/:comment_id' });
});
});

Ember Router rootURL option (Uncaught Error: No route matched the URL '/admin')

I'm trying to start to build a admin system that will run on a /admin/ prefix.
Here is my routes file
App.Router.reopen
location: 'history'
rootURL: '/admin'
App.IndexRoute = Ember.Route.extend
setupController: (controller, model) ->
#controllerFor('application').set('currentRoute', 'home')
When I go to /admin I get the following error:
Uncaught Error: No route matched the URL '/admin'
I'm just starting with emberjs, and my code is based on this serie
Ember version: v1.0.0-pre.4
Ember-data current api revision:: 11
In old-router the 'rootURL' property would have been ignored when resolving routes. In the latest version of ember, rootURL only seems to be used when constructing links. Not sure if this is a bug or oversight. As a workaround, try this instead:
App.Router.map(function() {
this.resource("admin", { path: "/admin" }, function() {
this.route("other");
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('admin');
}
});
When talking about routing in emberjs, it depends which version you are using. There was a big API change between 1.0pre2 and 1.0pre3. The docu on www.emberjs.com is already up-to-date for the new API and and easy to understand.
Below a really small example that shows
IndexRoute that automatically redirects to the overview of all members at '/members'.
Dynamic routing based on an ID
Serialization/Deserialization in case that the parameter is not 'id' but something else. In the example below, it is 'refId' (stands for reference ID).
Well, the examle does not really show more than the official documentation. but add-on information is always nice.
So, hope this helps. cheers.
App.Router.map(function() {
this.resource("members", { path: '/members' });
this.resource("member", { path: "/members/:refId" }, function() {
this.route("delete");
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('members');
}
});
App.MembersRoute = Ember.Route.extend({
model: function() {
return App.Member.findAll();
}
});
App.MemberRoute = Ember.Route.extend({
model: function(params) {
return App.Member.find(params.refId);
},
// overwrite default serializer (defaults to 'id', member has 'refId')
serialize: function(model) {
return { refId: model.refId };
}
});