Nested routes in ember engine routes.js? - ember.js

How to define nested routes in ember routable engine? I can't navigate to beyond 2 trees. Like,
For example
All posts
Post
Comments
Comment
I can access
localhost:4200/posts/:postid/
But when I access
localhost:4200/posts/:postid/comments/:commentid
Its not rendering the content for comments template. But it doesn't show any error either.

In your terminal
$ ember g route posts
$ ember g route posts/post
$ ember g route posts/post/comments
$ ember g route posts/post/comments/comment
In your router.js, replace the contents by the following
Router.map(function(){
this.route('posts', function() {
this.route('post', {path: '/:post_id' }, function() {
this.route('comments', function() {
this.route('comment', {path: '/:comment_id'});
});
});
});
});
This is a solution, But what I prefer is , define an index sub-route in every main routes, for example ember g route posts/index and add it into your router.js like
this.route('posts', function() {
this.route('index', {path: '/'});
this.route('post', {path: '/:post_id'}, function() {
.....
.....
});
});
add an index sub route every time

Related

Multiple nested routes in Ember.js having weird behaviour

I'm starting out on Ember.js and I have a three level route for one of the pages. This is what the router map looks like:
App.Router.map(function(){
this.resource('tests');
this.resource('create', function() {
this.resource('create.questions', {path: ':test_id' }, function() {
this.resource('create.questions.question', {path: ':question_id'});
});
});
});
In my CreateRoute, I transition onto the create/questions route using the following code:
this.get('controller').transitionToRoute('create/questions', test);
Which works fine, but in my CreateQuestionsRoute, this code doesn't work:
this.get('controller').transitionToRoute('create/questions/question', question);
The error received:
Uncaught Error: Assertion Failed: Error: Assertion Failed: The route create/questions/question was not found
Using the Chrome Ember inspector plugin, I can see the routes are listed as such:
CreateRoute
CreateQuestionsRoute
CreateQuestions.QuestionRoute
This seems like arbitrary behaviour. There isn't much guidance on how to handle multiple nested routes. Some references told me that my route map should actually look like this:
App.Router.map(function(){
this.resource('tests');
this.resource('create', function() {
this.resource('questions', {path: ':test_id' }, function() {
this.resource('question', {path: ':question_id'});
});
});
});
Whereby the route name would automatically be nested (no need for dot notations), but this did not work. Can anyone with Ember wisdom shine some light for me?
Go with this:
App.Router.map(function(){
this.resource('tests');
this.resource('create', function() {
this.resource('questions', {path: ':test_id' }, function() {
this.resource('question', {path: ':question_id'});
});
});
});
The only reason to add namespace a resource is if the resource isn't unique. Which means from any route you can use
this.transitionTo('questions', model);
this.transitionTo('question', modelForQuestions, modelForQuestion);
Example: http://emberjs.jsbin.com/OxIDiVU/636/edit
If you want to keep your namespace, I'd go with camelCase instead of dot notation, since generally the dot means property on the current scope.
Example: http://emberjs.jsbin.com/OxIDiVU/637/edit

Why two router Emberjs error

I have code emberjs router is below.I have two router App.CateProductRoute and App.ProductRoute
then
console.log("CateProduct"); not run function show console
console.log("Product"); run function show console
App = Ember.Application.create();
App.Router.map(function () {
//Product
this.resource('cateproduct', function () {
this.route('cateproduct', { path: 'cateproduct/:id' });
});
this.resource('product', function () {
this.route('product', { path: 'product/:id' });
});
})
App.IndexRoute = Ember.Route.extend({
model: function () {
return {};
}
});
App.CateProductRoute = Ember.Route.extend({
model: function () {
console.log("CateProduct"); not is run show
}
});
App.ProductRoute = Ember.Route.extend({
model: function () {
console.log(" Product"); is run show
}
});
Ember doesn't know that you want to camelCase your CateProduct Route and therefore instead of using your declared CateProduct Route, Ember is creating the missing Route --> CateproductRoute.
Conclusion: Rename your CateProduct Route (and all Controllers, Models, etc.) to Cateproduct or rename your resource to cateProduct (just rename the resource, the path can remain the same) and everything should work with CateProduct too :) - also, for this type of routing you won't need the inner routes - everything works without them pretty well
so, you either have:
App.Router.map(function () {
this.resource('cateProduct', {path: 'cateproduct/:id'});
this.resource('product', {path: 'product/:id'});
});
and keep your CateProduct named Route/Controller/Model
or you have:
App.Router.map(function () {
this.resource('cateproduct', {path: 'cateproduct/:id'});
this.resource('product', {path: 'product/:id'});
});
and rename your Route/Controller/Model to match Cateproduct

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!

Emberjs equivalent of root to: "something" in Rails route

In emberjs routes, I have
App.Router.map(function() {
this.resource('about');
this.resource('projects');
});
about page shows up when I hit /about and projects page shows up when I hit /projects.
How do you make the about page show up even in / as well as /about?
Rails equivalent of would be something like
root to: "pages#about"
get 'about', to: 'pages#about'
get 'projects', to: 'pages#projects'
By default ember generates a IndexRoute mapping to '/'
App.Router.map(function() {
// By default ember generates a IndexRoute mapping to '/'
// this.route('index', { path: '/' });
this.resource('about');
this.resource('projects');
});
App.IndexRoute = Ember.Route.extend({
beforeModel: function() {
this.transitionTo('about');
}
});
So you can override the beforeModel from IndexRoute to transition to about route.

View Controller not getting called

I have set up a view in ember and rendered it on the page like this
App.TestView = Ember.View.extend({
template: Ember.Handlebars.compile('<h1>Heading</h1>')
});
{{view App.TestView}}
But if I create the controller nothing happens
App.TestController = Ember.Controller.extend({
init: function() {
console.log('CONTROLLER HERE');
this._super();
}
});
Any ideas why this happens?
When you create a view manually (like you are doing) it doesn't use the test controller. If you hit a test route it will use the associated test controller and test view.
In your case based on your comments below you probably want to set up some routes and have them use the associated controllers and views.
Check out this: http://emberjs.com/guides/routing/defining-your-routes/
Maybe something like this
App.Router.map(function() {
this.resource('gallery', { path: '/gallery/:gallery_id' }, function() {
this.resource('photo', { path: 'photo/:photo_id' });
});
});
You are missing a route for your example to work: http://jsbin.com/IGIvuhe/2/edit
Add this and it will work:
App.Router.map(function(){
this.route("test", {path: '/'});
});
Hope it helps.