This one has me baffled. I am still new to ember but I had some nested routes where I was calling transitionTo with the redirect hook on the parent route to pull in a nested child route.
App.CategoryRoute = Ember.Route.extend({
redirect: { transitionTo('subcategories'); }
});
I since removed the redirect hook and the transitionTo however the transition is still occurring. I even have closed my project and reopened, cleared the cache on all browsers but it still is holding onto the transition. I have also tried calling a bogus route under the redirect and it errors out. As soon as I remove, it goes back to this behavior and transitions into the child route. Has anyone ever had this happen? What am I doing wrong? Please let me know if you need more code.
Here is the rest of the code. in my troubleshooting i have removed and added so much stuff I will try to get it back to what it was when it started happening. I also removed as much 'fluff' as I could from the handlbars code sections to make it clearer.
App = Ember.Application.create({
rootElement: "#app",
LOG_TRANSITIONS: true
});
App.Router.map(function () {
this.resource("category", function () {
this.resource('subcategories', { path: "/" }, function () {
//subcategory route show list of items in that subcategory
this.resource('subcategory', { path: "/:subcategoryslug" }, function () {
//this is individual item
this.route("item", { path: "/:itemid" });
});
});
});
});
App.CategoryRoute = Ember.Route.extend({
redirect: { transitionTo('subcategories'); }
});
App.CategorySubcategoriesRoute = Ember.Route.extend({
model: function (params) {
Ember.Logger.warn("Inside category route");
categoryid = 47
//this calls extended object for json data
//works just fine when routes are rendered.
return App.Subcategory.findAll(categoryid);
}
});
Here is the handlebars blocks:
<script type="text/x-handlebars" data-template-name="index">
<h2>APPLICATION TITLE</h2>
<div>
<strong>{{#link-to 'category'}}CategoryName{{/link-to}}</strong>
</div>
</script>
<script type="text/x-handlebars" data-template-name="category/index">
<h2>Category Name</h2>
<div>
{{outlet "subcategories"}}
</div>
</script>
<script type="text/x-handlebars" data-template-name="category/subcategories">
{{#each subcategory in model}}
<div>
<strong>{{#link-to 'category.subcategory.index' subcategory}}{{subcategory.subcategoryname}}{{/link-to}}</strong><br>
{{subcategory.description}}
</div>
{{/each}}
</script>
Related
I am new to Ember.js, and I am trying to learn it by rewriting an old app of mine. Unfortunately I got stuck fairly early and need some help, as couldn't find the answer on the Web.
I have the following code:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function () {
this.resource("users", function () {
this.resource("score", {path: "/:nickname"});
});
});
App.UsersRoute = Ember.Route.extend({
model: function () {
var url = "server url";
return new Ember.RSVP.Promise(function (resolve, reject) {
resolve($.getJSON(url));
});
}
});
App.ScoreRoute = Ember.Route.extend({
model: function () {
var url = "server url" + "?nickname=";
url += passedNicknameFromclickedLink;
return new Ember.RSVP.Promise(function (resolve, reject) {
resolve($.getJSON(url));
});
}
});
<script type="text/x-handlebars">
<nav>
{{#link-to "users"}}Users{{/link-to}}
</nav>
<main class="main-wrapper">{{outlet}}</main>
</script>
<script type="text/x-handlebars" data-template-name="users">
<div class="user-score">{{outlet}}</div>
<h2>Users</h2>
{{#each}}
<div>{{#link-to "score" nickname}}{{nickname}}{{/link-to}}</div>
<div>{{games}}</div>
<div>{{score}}</div>
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="score">
<h2>Score for {{nickname}}</h2>
{{#each categoryScores}}
<div class="scores">
<div>{{category}}</div>
<div>{{gamesPlayed}}</div>
<div>{{score}}</div>
</div>
{{/each}}
</script>
What I am trying to do is to take the {{nickname}} property clicked by the user in the {{#link-to}} in "users" template and pass it as "passedNicknameFromclickedLink" variable to App.ScoreRoute in order to make a server request. I was wondering what is the proper way to do this?
It looks like you've almost everything right, you just need 2 things. First, you can access the nickname dynamic segment in the model hook with the params parameter.
model: function(params) {
var passedNicknameFromclickedLink = params.nickname;
}
Secondly, because Ember assumes quite a few conventions with your route and models, you'll have to override the serialize method in the route as well. With the serialize method, what you want to do is start with your model (the JSON from the server) and give back the nickname that was used to find that model. I don't know exactly what your JSON looks like, but it might look something like this:
serialize: function(model) {
return encodeURI(model.nickname);
}
Apologies if this isn't quite the right place (as opposed to either libraries own github issue page, but as I've not been able to determine exactly which library is not quite working correctly hard to log it specifically).
I'm using ember data fragments on my model (an array), and localstorage to save down my model. When calling rollback upon the saved model, it seems to reset the fragments back to their original state (i.e. no values), but it still maintains the fragment itself on the array, rather than dropping the item out of the array.
I've got a fiddle setup, click 'add' to add a model, click to view it's details, then click 'add' in there, followed by 'cancel'. You can see that the type + desc values drop out, but the element is still there.
If I switch out to using the Fixture adapter then it all works as expected, just not sure where to start even attempting to debug, I've stepped through many lines of _super calls, and what not trying to figure it out, but just get lost.
Note
This is a pseudo version of my actual app, and curiously enough when you navigate to the home page and then back to the details page, it seems to resolve the type/desc correctly, which it is not doing on my actual app, it still maintains the default values. However refreshing the page makes it work perfectly from then onwards.
Any help greatly appreciated!
<!DOCTYPE html>
<html>
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="//builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="//builds.emberjs.com/tags/v1.7.0/ember.js"></script>
<script src="//builds.emberjs.com/canary/ember-data.js"></script>
<script src="//raw.githubusercontent.com/lytics/ember-data.model-fragments/master/dist/ember-data.model-fragments.js"></script>
<script src="//raw.githubusercontent.com/kurko/ember-localstorage-adapter/master/localstorage_adapter.js"></script>
<script>
window.App = Ember.Application.create();
App.ApplicationStore = DS.Store.extend();
App.ApplicationSerializer = DS.LSSerializer.extend();
App.ApplicationAdapter = DS.LSAdapter.extend({
namespace: 'cars'
});
App.Car = DS.Model.extend({
make: DS.attr(),
model: DS.attr(),
features: DS.hasManyFragments('feature')
});
App.Feature = DS.ModelFragment.extend({
type: DS.attr(),
description: DS.attr()
});
App.Router.map(function () {
this.route('index', { path: '/' });
this.route('car', { path: '/car/:car_id'});
});
App.IndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('car');
},
actions : {
add: function(model) {
var car = this.store.createRecord('car', {
make: 'Dodge',
model: 'Viper',
features: []
});
car.save();
}
}
});
App.CarRoute = Ember.Route.extend({
actions: {
add: function(model) {
model.get('features').createFragment({
type: 'Something',
description: 'Some desc'
});
model.save(); //*/
},
cancel: function(model) {
model.rollback();
}
}
});
</script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<script type="text/x-handlebars" data-template-name="index">
{{#link-to 'index'}}Home{{/link-to}}
<ol>{{#each}}
<li>{{#link-to 'car' this}}{{name}} {{model}}{{/link-to}}</li>
{{else}}
<button {{action 'add' model}}>Add</button>
{{/each}}</ol>
</script>
<script type="text/x-handlebars" data-template-name="car">
{{#link-to 'index'}}Home{{/link-to}}
<dl>
<dt>Make</dt>
<dd>{{make}}
<dt>Model</dt>
<dd>{{model.model}}</dd>{{#each features}}
<dt>{{_view.contentIndex}}. {{type}}</dt>
<dd>{{description}}</dd>
{{/each}}
</dl>
<button {{action 'add' model}}>Add</button>
<button {{action 'cancel' model}}>Cancel</button>
</script>
</body>
</html>
I havent worked with data fragments but fragment is a model itself so the element/fragment is still there because you have created a record for it.
This record is stored in the ember store until you do something with it.
Rollback, via emberjs.com,does this - "If the model isDirty this function will discard any unsaved changes".
The model in this case seems to be the fragment. Rollback gets rid of the changes, which is what it is doing in your case, removing the type and desc values, but the record itself is still in the store.
If you want to get rid of the fragment altogether you would have to delete it. http://emberjs.com/guides/models/creating-and-deleting-records/
We have a scenario along these lines:
Quote
--->Create
So route names quote and quote.create.
The issue is that we need to render the templates into the main outlet. So in our main route (that all other are inherited from) we have this:
renderTemplate: function() {
this.render({ into: 'application' });
}
When I navigate to quote it renders the quote view. From there I navigate to quote.create and it renders the create view. However, going back to quote from quote.create renders nothing.
How can I get around this?
When I go back to the \quote url route 'quote.index' is sought. Since it is defined 'automagically' nothing happens. When I define the route explicitly ember tries to find the quote.index template and view and these do not exist.
A workaround I tried is to have this:
App.QuoteIndex{Route|Controller|View} = App.Quote{Route|Controller|View}.extend()
EDIT:
Hey diddle-diddle, here is my fiddle :) http://jsfiddle.net/EbenRoux/Mf5Dj/2/
Ember.js does not rerender a parent view when transitioning to a parent route, so using into with a parent view template is not recommended.
There is an easier way to create what you are trying to: use a quote/index route:
<script type="text/x-handlebars" data-template-name="application">
<h1>Rendering Issue</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="quote">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="quote/index">
<h2>Quote View</h2>
{{#linkTo 'quote.create'}}Create a new quote{{/linkTo}}
</script>
<script type="text/x-handlebars" data-template-name="quote/create">
<h2>Quote Create View</h2>
<p>Some controls would go here.</p>
{{#linkTo 'quote'}}Go back to quote view{{/linkTo}}
</script>
App = Ember.Application.create({});
App.ApplicationRoute = Ember.Route.extend({
activate: function () {
this.transitionTo('quote');
}
});
App.Router.map(function () {
this.resource('quote', function () {
this.route('create');
});
});
See http://jsfiddle.net/eYYnz/
I have just written extremly simple Ember app, built on top of the Rails app, working with Ember Data and displaying, creating and persisting just one entity type to the server. Everything with the latest tools (Ember v1.0.0-pre.4-134-gaafb5eb).
However, there is very strange problem I have encountered. My app has two views: entity list (index) and form for creating new entities. When I enter the index directly, everything displays OK. But when I go to the other view and then back to the list, the view is not rendered again. Where could be the problem?
I guess it might be caused by my (maybe incorrect) using new Ember router. So I'm pasting important (from my point of view) parts of the app here:
Router:
App.Router.map(function() {
this.resource('bands', function() {
this.route('new');
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('bands');
}
});
App.BandsRoute = Ember.Route.extend({
model: function() {
return App.Band.find();
}
});
App.BandsNewRoute = Ember.Route.extend({
renderTemplate : function(){
this.render('bands_new',{
into:'application'
});
}
});
Link back to list - which does not work:
App.BandsNewController = Em.ArrayController.extend({
cancel: function() {
this.transitionTo('bands');
}
});
Have a look at the whole app here: https://github.com/pavelsmolka/roommating
(It's hugely inspired by great https://github.com/dgeb/ember_data_example)
I don't believe it, but could it be bug in Ember itself?
I think your "render" call in your BandsNewRoute is messing things up.Try making things go more with Ember defaults. So I would refactor your app to do this:
(working fiddle: http://jsfiddle.net/andremalan/DVbUY/)
Instead of making your own render, all you need to do is create a "bands" template (it can be completely empty except for {{outlet}} if you want) and a "bands.index" template.
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="bands/index">
<h2>Bands Index</h2>
{{#linkTo bands.new}}New Band{{/linkTo}}
</script>
<script type="text/x-handlebars" data-template-name="bands">
<h1>Bands</h1>
<p>
{{#linkTo index}}Start Again{{/linkTo}}
{{#linkTo bands.new}}New Band{{/linkTo}}
</p>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="bands/new">
I'm in new band!
<a {{action "cancel"}}>Cancel</a>
</script>
Your routes also clean up really nicely this way:
App.Router.map(function() {
this.resource('bands', function() {
this.route('new');
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('bands');
}
});
App.BandsNewController = Ember.Controller.extend({
cancel: function() {
this.transitionTo('bands');
}
});
I hope that helps!
What I have so far:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function(match){
match('/').to('application');
match('/edit').to('edit');
});
App.ApplicationRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('edit');
},
events: {
startEdit: function( context ){
this.transitionTo( 'edit' );
}
}
})
App.EditRoute = Ember.Route.extend({
init: function(){
this._super()
console.log('EditRoute')
},
});
Handlebars:
<script type="text/x-handlebars" data-template-name = 'application'>
Hello World
{{ outlet main }}
</script>
<script type="text/x-handlebars" data-template-name = 'edit'>
<div class = 'edit-background'> Edit State: {{ title }} </div>
</script>
I have four questions:
When I open the application it just remains in the home page, is the redirectTo hook suppose to immediately redirect you to another state?
In addition, I have this events hash in AplicationRoute per suggestion from here: How to programmatically transition between routes using Ember.js' new Router. but I read through the answers and still am not sure how you are supposed to use it.
How do I test the router on the console? before you could navigate between the states by calling transitionTo commands, what do I do now?
For some odd reason, my application template seem to rendered twice, as in there are two 'Hello World' up there, and when try to add something like: <li>{{#linkTo edit}}edit{{/linkTo}}</li>
I get this error:
'Uncaught TypeError: Cannot read property 'container' of undefined -- ember.js:2223'
This is how you would initially load the editView/route/template on application start up:
Router
App.Router.map(function(match){
match('/').to('application',function(match){
match('/').to('edit')
})
})
ApplicationTemplate
<script type="text/x-handlebars" data-template-name="application">
{{outlet}}
</script>
EditTemplate
<script type="text/x-handlebars" data-template-name="edit">
I am embedded!
</script>
EditRoute
EditRoute = Ember.Route.extend({
renderTemplates:function () {
this.render('edit', {
into:'application'
});
})