transitionTo('route', context) passes context base route, not to the route requested - ember.js

I am working on an Ember app where I wish a button click to transition to a new route passing an object as the context for that route.
The problem is, no matter how I try and pass that context, it is always lost by the time I get to the route I am transitioning to.
Investigating (http://jsfiddle.net/fxbXM/2/) it seems that the the context is passed to the first route the router hits as it works to the requested route. (See the output of the connectOutlets function from each route level)
This seems to confirm what I thought I had found when debugging my actual app: in the triggerSetupContext function of Ember there are three enterStates: [Router, 'root', 'create'] and there are three contexts: [myObject, null, null]
If the contexts were in the opposite order then I would get what I wanted where I wanted it!
Am I making some fundamental error in the way i'm passing the object as a context? Should I be using another approach?

A bit tricky to realize what does'nt work... while debugging, I found this: in routers, only states with dynamic segments have a context, so in the create route, I added ":widget_id", and it seems to work. see http://jsfiddle.net/Sly7/EqyUa/
It seems that if you don't have any dynamic segment in your route, you can't pass a context to it. It would be great if I can have confirmation of that...
Update
Searching on github repo, I found this issue: #1118. In the last comment, Yehuda explain why this does not make sense to pass a context to connectOutlets without dynamic segment.

Related

When should I use controllers vs routes in EmberJS?

I know this question might seem a little duplicate but the other version of this question is old and some of the content (such as Views) aren't even a part of ember anymore.
I'm about 4 weeks into my internship as a front-end developer working with EmberJS. I still don't understand when it's better to use the route over the controller or vice-versa. It seems to me that every action in the route can also be used in the controller.
The one recent thing I heard was that ember routes should be stateless where as controllers should be stateful.
What is the current state of controllers and routes. When should one be used over the other?
Consider the following example to understand the state of a controller (or route, or anything), in simple terms and in current context -- lets say you have a page (like a form) with three tabs; each tab can be considered as a state - it would call different components based on the state (or the tab you are in). Now if you would happen to go back for some reason, and hit the form link again, you would see that the state would remain the same. (if you were on tab 2 when you hit back, on returning to the form, you would still be on tab 2).
So to maintain these states, controllers are the way to go, since they are singletons. Route would have lost that information, and started fresh. So basically your variables/objects in a controller would define the 'state'.
Route-actions can be as easily used as controller actions- see https://github.com/DockYard/ember-route-action-helper. So if your template for this route is just using model as the object directly, and you don't need to maintain the 'state', you can pretty much do without your controller.
But if your template was using variables which needed manipulation, you would need controller.
Hope this helps!

Customize loading template for non-nested ember route

Using ember: 1.7.0
I'm trying to used different loading templates depending on the route that is being transitioned to in my app. None of my routes are nested (i.e. contained within a resource). I've only been able to get ember to serve up the application loading template. Is there a way to override this behavior in the case of non-nested routes?
Here's a jsbin illustration the problem:
Two loading templates are defined loading and top-loading.
When loaded up the app transitions to the top route.
I was hoping this would trigger the top-loading template, but instead it triggers the loading template.
http://emberjs.jsbin.com/pamego/1/
Thanks in advance for any assistance!
I'm going to do that thing where I question a premise of your question:
If your routes aren't nested then there should be no harm in treating them as resources. Routes only have special behavior when they are nested (they don't reset their namespace).
Conceptually, changing this route to a resource works. The "loading" state is really an enhancement or a special form of "top". When something has multiple states like this, modeling it as a resource makes sense. With all that preamble, I propose this:
http://jsbin.com/javihuceqo/1/edit?html,js,output
The problem is that your route is only nested one level deep, so the application-level loading substate is active. If you had a Route that was 2 levels down, "FooBar", for example, then trying to load the FooBarRoute model would cause the foo/loading template to be displayed.
Please see this jsbin for an example.

multiple Independent routes in Ember.js

I'm looking for a way to get multiple independent routes, managed by the url in Ember.js. The Goal is, to get a Page that shows Persondata and Personrelated data on the Same Page. Here is a Mockup I created for better understanding:
https://www.dropbox.com/s/carcorg1ox0qjgd/Mockup.png (not enough reputation to post images, sry!)
I imagine a Start-URL like:
"#/person/123/Persondetails/Audi/Vehicledetails"
The Idea is, that I can change from Persondetails to Adresses without affecting the Bottom Part of Vehicledetails. The new URL should look like:
"#/person/123/Adresses/Audi/Vehicledetails"
And vice versa, changing from Vehicledetails to Engine, but stay on the Adresses route for Persondetails. The new URL should look like:
"#/person/123/Adresses/Audi/Engine"
I've already found an interesting thread to start with, but it shows only level of the dynamic Part of Routes. I'm experimenting with the router for a few days now and feel kinda stuck. Is it even possible to acchieve what I want with Ember?
I'd be very grateful for every little hint you can give me!
Unfortunately the router doesn't support this type of architecture.
It's possible someday you could hack it in with query-string params, but you'll lose a lot of the built in functionality going this route.
Ember routing design. Desktop like routes

accessing the model from the template

Playing around with ember, I found that sometimes the model is stored on the controller's content property, sometimes the model is directly available on the controller as well. I do not understand however, when this is the case.
Let me explain it by an example which I found when assembling my ember MVC.
Setup A - The start
I defined a custom Member object, corresponding MemberRoute, MemberView classes and a template with the name member.
The Member object had some attributes such as id, nickname, etc.
NOTE: no controller of the form MemberController was defined, thus by ember's convention, it provides the controller on its own.
Setup B - The customization
Same as setup A, but now there is a MemberController defined that contains some action methods that are triggered from within the template.
The strange behaviour (resp. what I do not completely understand)
in setup A, I can refer to the Member's attributes directly with {{id}} or {{nickname}}.
in setup B, I have to use {{content.id}} or {{content.nickname}}
As documented in ember's documentation, MemberView does
setupController : function(controller, member) {
controller.set('content', member);
},
So, could somebody help me to understand why the difference and where the difference is? Currently, my guess would be either
that the context of the template is different (possibly there is a code piece missing in the setup of the controller?)
or
the default controller that is provided by ember automatically, has some additional magic that is not directly avaiable for customized controllers.
Any help to understand this is highly appreciated. It already took my quite a while to come as far as this. I first thought it could be the modularization introduced by the project setup with requireJS (well, I still think that could have a influence). Ember is v1.0pre4.
Thanks in advance!
Patrick
So, could somebody help me to understand why the difference and where the difference is? Currently, my guess would be either
that the context of the template is different (possibly there is a code piece missing in the setup of the controller?)
or
the default controller that is provided by ember automatically, has some additional magic that is not directly avaiable for customized controllers.
It's hard to say for sure without seeing your code, but my best guess is that your MemberController extends Ember.Controller. The default provided by ember (in this scenario) would have been an Ember.ObjectController. If that's what you want, change your MemberController definition to:
App.MemberController = Ember.ObjectController.extend({
myProperty: 'value'
});
An objectController acts as a proxy to it's content property, typically that is an ember model. So if things are wired up correctly you should never need to access a model via the 'content` property. If you ever see something like:
{{content.id}} or {{content.nickname}}
it's a sign that you should change to an ObjectController. See EMBER GUIDES: REPRESENTING A SINGLE MODEL! for a more detailed explanation.
an ObjectController acts as proxy to the object set to the controller's content. When no controller is defined, Ember will create a controller for you and set its content by default to whatever object is returned by the model() function, if defined, in the route. The behaviour should be the same whether you define your own controller or let Ember define one for you
The default context in the template is the controller itself i.e. this = an instance of your controller or the generated one. When you try to access nickname in that context, Ember will first try to resolve it against the controller itself and if nothing is found, it resolves it against its content, i.e the object if you already manually set it to the controller's content.
Finally, there is no default implementation of the model() function in the Route except when you're using dynamic urls, say /foo/id that resolves against /foo/:id, Ember uses the id provided to load a Foo object with the id provided, thus providing a default implementation to the model() function. At the end it boils down to the same mechanism, only automated for your convenience.
I suggest you listen to this for more insights on how things are automated for you by Ember. But when it comes to the content being displayed, there is no magic you have to manually wire the content of the controller.

Troubleshooting Routes and States with Ember.js

I should start by saying that I'm a complete Ember.js noob (and MVC JavaScript Framework noob in general).
I'm trying to figure out how the Router and StateManager work together. I've cobbled together an example from various places on the interwebs, you can view it here:
http://jsfiddle.net/zdfs/qsAxZ/1/
So everything on first load seems like it's working. But there are pieces of the function that don't seem to be behaving properly. I want the CSS classes that I attach via the action links to actually be a part of the application state, but I have something messed up somewhere.
You can duplicate the problem by clicking "webcam" or "screensharing". The link will highlight. When I reload the page, the state is correct, but the highlight is lost. I'm doing something incorrectly, but I don't know how to fix it.
If I try to move the actions into the StateManager, then the router.get("applicationController") reference is lost.
I also can't do something like sManager.send("goHome"); - problems occur.
Some remarks after reading your code:
Is there a reason why you did split your code between a Router & a StateManager? In the current canonical form, your states should be classes of Ember.State, located inside the router.
The connectOutlet method should be called from the connectOutlets state's hook, not the enter one.
The event handlers in the router get the router instance in first parameter, not a state (cf. goHome, viewWebcam & viewScreen)