this post has a lot of detail so please bear with me
Most of my Ember.js development experience is pre-release (0.9.8.1) and I'm fairly new to routes. I've put in a lot of time understanding them and have created a working app:
Problem is, my code intermittently doesn't work (mostly noticeable in Chrome). At first, I was having problems with ember not finding the templates. I was overriding the view for a route and specifying the template like so:
scripts/users.js
define(['scripts/app','text!scripts/templates/UserIndex.html'],
function (app, templateUserIndex) {
//route is called app.UserIndexRoute
app.UserIndexView = Ember.View.extend({
template: Ember.Handlebars.compile(templateUserIndex),
Created: function () {
return app.ParseDate(this.get('controller.model.created')).toLocaleDateString();
}.property('controller.model.created'),
MailTo: function () {
return 'mailto:' + this.get('controller.model.email');
}.property('controller.model.email')
});
});
I verified requirejs loads the html using the text plugin... but then found that other folks on StackOverflow had problems with using "template" with views in routed objects. So instead of fighting that, I removed the" template" line and updated my App class to explicitly set the templates for all my views in the ready() event (since I know the route will default the template name)
scripts/app.js
define(['jquery',
'handlebars',
'ember',
'text!scripts/templates/Application.html',
'text!scripts/templates/Loading.html',
'text!scripts/templates/Index.html',
'text!scripts/templates/OwnedCarsIndex.html',
'text!scripts/templates/OwnedCar.html',
'text!scripts/templates/UserIndex.html'],
function (jQuery, handlebars, ember, templateApplication, templateLoading, templateIndex, templateOwnedCarsIndex, templateOwnedCar, templateUserIndex) {
App = Ember.Application.create({
ready: function () {
Ember.TEMPLATES['application'] = Ember.Handlebars.compile(templateApplication);
Ember.TEMPLATES['loading'] = Ember.Handlebars.compile(templateLoading);
Ember.TEMPLATES['index'] = Ember.Handlebars.compile(templateIndex);
Ember.TEMPLATES['ownedCars/index'] = Ember.Handlebars.compile(templateOwnedCarsIndex);
Ember.TEMPLATES['ownedCar'] = Ember.Handlebars.compile(templateOwnedCar);
Ember.TEMPLATES['user/index'] = Ember.Handlebars.compile(templateUserIndex);
},
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true,
LOG_VIEW_LOOKUPS: true,
LOG_ACTIVE_GENERATION: true
});
App.Router.map(function () {
this.resource('users', function () {
this.resource('user', { path: ':user_id' }, function () {
this.resource('ownedCars', { path: 'cars' }, function () {
this.resource('ownedCar', { path: ':ownership_id' }, function () {
this.resource('expenses');
});
});
});
});
this.resource('cars', function () {
this.resource('car', { path: ':car_id' });
});
});
return App;
});
This solved the templates intermittently not loading. But now, again intermittently, I am running into an issue with the route. I have a link-to helper and here is some of the console output for when the page experiences this issue:
DEBUG: -------------------------------
DEBUG: Ember : 1.3.0
DEBUG: Handlebars : 1.1.2
DEBUG: jQuery : 1.10.2
DEBUG: -------------------------------
Attempting URL transition to /
generated -> route:application Object {fullName: "route:application"}
generated -> route:index Object {fullName: "route:index"}
Transition #1: Beginning validation for transition to index
Transition #1: application: calling beforeModel hook
Transition #1: application: resolving model
Transition #1: application: calling afterModel hook
Transition #1: application: validation succeeded, proceeding
Transition #1: index: calling beforeModel hook
Transition #1: index: resolving model
Transition #1: index: calling afterModel hook
Transition #1: index: validation succeeded, proceeding
Transition #1: Validation succeeded, finalizing transition;
generated -> controller:application Object {fullName: "controller:application"}
Rendering application with default view <(subclass of Ember.View):ember209> Object {fullName: "view:application"}
generated -> controller:index Object {fullName: "controller:index"}
Rendering index with default view <Ember._MetamorphView:ember225> Object {fullName: "view:index"}
Transitioned into 'index'
Transition #1: TRANSITION COMPLETE.
generated -> route:cars Object {fullName: "route:cars"}
generated -> route:cars.index Object {fullName: "route:cars.index"}
generated -> route:users Object {fullName: "route:users"}
generated -> route:user Object {fullName: "route:user"}
generated -> route:user.index Object {fullName: "route:user.index"}
but when I try to click the "Edit profile" link, which was generated with the link-to helper, I get this:
Attempting transition to user.index
Transition #2: Beginning validation for transition to user.index
Transition #2: application: using context from already-active handler
Transition #2: application: validation succeeded, proceeding
Transition #2: users: calling beforeModel hook
Transition #2: users: resolving model
Transition #2: users: calling afterModel hook
Transition #2: users: validation succeeded, proceeding
Transition #2: user: calling beforeModel hook
Transition #2: user: resolving model
Assertion failed: You used the dynamic segment user_id in your route user, but App.User did not exist and you did not override your route's `model` hook.
Transition #2: user.index: transition was aborted
I'm not sure why it's trying to access App.User, instead of App.UserRoute (App.UserRoute has the overloaded model function, which correctly generates a model)
Any help is very much appreciated :)
UPDATE: One problem I was having (which I didn't even mention) I solved- I needed to shim Ember.js using requirejs's config:
require.config({
paths: {
'text': 'scripts/references/text',
'jquery': 'scripts/references/jquery-1.10.2.min',
'handlebars': 'scripts/references/handlebars-1.1.2',
'ember': 'scripts/references/ember-1.3.0'
},
shim: {
'ember': {
deps: ['handlebars', 'jquery'],
exports: 'Ember'
}
}
});
This got rid of intermittent "module jquery not found" or "module handlebars not found" (which only happened when the cache was dumped). The main issue described is still present though. From the debugger console, here is the only difference I noticed when it renders the page...
Working page
Transition #1: TRANSITION COMPLETE.
generated -> route:cars Object {fullName: "route:cars"}
generated -> route:users Object {fullName: "route:users"}
Not working page (errors when you click link)
Transition #1: TRANSITION COMPLETE.
generated -> route:cars Object {fullName: "route:cars"}
generated -> route:cars.index Object {fullName: "route:cars.index"}
generated -> route:users Object {fullName: "route:users"}
generated -> route:user Object {fullName: "route:user"}
generated -> route:user.index Object {fullName: "route:user.index"}
If you notice the non-working page output, Ember is generating route objects for routes that aren't being used yet... Why is this only happening sometimes?