Controller.set in IndexRoute - ember.js

I have following js code:
App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.Router.map(function() {
this.resource('posts');
this.resource('about');
});
App.IndexRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('title', "test");
}
});
App.PostsRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('title', 'test');
}
});
And following html page:
<script type="text/x-handlebars">
<div class="container">
<div class="navbar">
<div class="navbar-inner">
<ul class="nav">
<li>{{#linkTo index}}Home{{/linkTo}}</li>
<li>{{#linkTo posts}}Posts{{/linkTo}}</li>
<li>{{#linkTo about}}About{{/linkTo}}</li>
</ul>
</div>
</div>
{{title}} // <--- no title here
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="about">
About template
</script>
<script type="text/x-handlebars" id="posts">
<h1>{{title}}</h1> // <--- works here
Recent posts
</script>
I got rendered {{title}} variable only at posts route. It doesn't work at index route though. I was reading manual and tried to do exactly as is mentioned there: http://emberjs.com/guides/routing/defining-your-routes/

Related

Assertion failed: Your server returned a hash with the key category but you have no mapping for it

Note really sure what to do. I'm trying to use a slug instead of ID but when I try to go directly to a link (/categories/source), I get the error. I've tried adding mappings in the RESTadapter but it hasn't worked. I ha
I've a feeling that my problem is in my CategoryRoute/model code but I can't see to get the right combo. Any help is appreciated.
To be honest, I don't know why it has to make two REST calls when it's already got the model info available. Any help is appreciated, thanks!
Json responses
{"categories":[{"id":1,"name":"Misc","slug":"misc"},{"id":2,"name":"Technology","slug":"technology"},{"id":3,"name":"Ecommerce","slug":"ecommerce"},{"id":4,"name":"Visitor","slug":"visitor"},{"id":5,"name":"Content","slug":"content"},{"id":6,"name":"evars","slug":"evars"},{"id":7,"name":"Marketing","slug":"marketing"},{"id":8,"name":"Props","slug":"props"},{"id":9,"name":"Source","slug":"source"}]}
{"category":{"id":2,"name":"Technology","slug":"technology"}}
Html file
<script type="text/x-handlebars">
<div class="container">
<div class="navbar navbar-inverse">
<a class="navbar-brand" href="#">LayerSpark</a>
<ul class="nav navbar-nav">
<li>{{#linkTo 'categories'}}Categories{{/linkTo}}</li>
<li>{{#linkTo 'help'}}Help{{/linkTo}}</li>
<li>{{#linkTo 'account'}}Account{{/linkTo}}</li>
</ul>
</div>
</div>
<div class="container">
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="categories">
<div {{bindAttr class=":row"}}>
<div {{bindAttr class=":col-lg-4"}}>
<ul>
{{#each model}}
<li>{{#linkTo 'category' this}}{{name}}{{/linkTo}}</li>
{{/each}}
</ul>
</div>
<div {{bindAttr class=":col-lg-8"}}>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" id="category">
Post:<br>
My name is :: {{ name }}<br>
My id is :: {{id}}<br>
My slug is :: {{slug}}<br>
</script>
<script type="text/x-handlebars" id="categories/index">
<p class="text-warning">Please select a Category</p>
</script>
App.js
App = Ember.Application.create({
LOG_TRANSITIONS:true
});
var attr = DS.attr;
App.Category = DS.Model.extend({
name: attr('string'),
slug: attr('string')
});
DS.RESTAdapter.configure("plurals", {
category: "categories"
});
App.Store = DS.Store.extend({
revision: 12,
adapter: DS.RESTAdapter.create({
url: '/api',
mappings:{
category:'App.Category'
}
})
});
App.Router.map(function() {
this.resource('about');
this.resource('categories', function() {
this.resource('category',{path:':category_slug'});
});
this.resource('help');
this.resource('account');
});
App.CategoriesRoute = Ember.Route.extend({
model: function() {
return App.Category.find();
}
});
App.CategoryRoute = Ember.Route.extend({
model: function(route,model) {
console.log(route);window.mod = model;
return App.Category.find({slug:route.category_slug});
},
serialize: function(model) {
return {
category_slug: model.get('slug')
};
}
});
Ember.Handlebars.registerBoundHelper('markdown', function(input) {
return new Handlebars.SafeString(showdown.makeHtml(input));
});
Ember.Handlebars.registerBoundHelper('date', function(date) {
return moment(date).fromNow();
});
I used the following router setup so that I could have a resource of Post corresponding to a route of /posts/:id. Also gives comments belonging to posts.
this.resource('posts', function() {
this.route('new');
});
this.resource('post', { path: '/posts/:post_id' }, function() {
this.resource('comments', function() {
this.route('new');
this.route('create');
});
this.route('comment', { path: 'comments/:comment_id'});
});
I had to define the categories resource separately and then explicitly state that post was under the /posts route in the definition of the resource. Maybe you need a router like:
this.resource('categories', function() {});
this.resource('category',{path:'/categories/:category_slug'});

Ember js using name for URL slug

Is it possible to use another field in the URL? I would like to use the name but I have apply toLowerCase() first which I'm doing in the specific object. Here's my code. Everything works but the object data doesn't show up in the view... Any ideas? Thanks in advance!
<body>
<script type="text/x-handlebars">
<div class="container">
<div class="navbar navbar-inverse">
<a class="navbar-brand" href="#">LayerSpark</a>
<ul class="nav navbar-nav">
<li class="active">{{#linkTo 'categories'}}Categories{{/linkTo}}</li>
<li>{{#linkTo 'help'}}Help{{/linkTo}}</li>
<li>{{#linkTo 'account'}}Account{{/linkTo}}</li>
</ul>
</div>
</div>
<div class="container">
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="categories">
<div {{bindAttr class=":row"}}>
<div {{bindAttr class=":col-lg-4"}}>
<ul>
{{#each model}}
<li>{{#linkTo 'category' slug}}{{name}}{{/linkTo}}</li>
{{/each}}
</ul>
</div>
<div {{bindAttr class=":col-lg-8"}}>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" id="category">
Post:<br>
My name is :: {{ categories.name }}<br>
My id is :: {{id}}<br>
My slug is :: {{slug}}<br>
</script>
<script type="text/x-handlebars" id="categories/index">
<p class="text-warning">Please select a Category</p>
</script>
<script type="text/x-handlebars" id="help">
<p class="text-warning">Help me</p>
</script>
<script type="text/x-handlebars" id="account">
<p class="text-warning">Your bank account is ...</p>
</script>
app.js
App = Ember.Application.create({
LOG_TRANSITIONS:true
});
DS.RESTAdapter.configure("plurals", {
category: "categories"
});
App.Store = DS.Store.extend({
revision: 12,
adapter: DS.RESTAdapter.extend({
url: '/api'
})
});
App.Router.map(function() {
this.resource('about');
this.resource('categories', function() {
this.resource('category',{path:':category_slug'});
});
this.resource('help');
this.resource('account');
});
App.CategoriesRoute = Ember.Route.extend({
model: function() {
return App.Category.find();
}
});
App.CategoryRoute = Ember.Route.extend({
setupController: function(controller, category) {
controller.set('model', category);
}
});
var attr = DS.attr;
App.Category = DS.Model.extend({
name: attr('string'),
slug: function(){
return this.get('name').toLowerCase();
}.property('name')
});
Ember.Handlebars.registerBoundHelper('markdown', function(input) {
return new Handlebars.SafeString(showdown.makeHtml(input));
});
Ember.Handlebars.registerBoundHelper('date', function(date) {
return moment(date).fromNow();
});
What you can do is to hook into the serialize hook of your CategoryRoute and provide there the slug.
Example:
App.CategoryRoute = Ember.Route.extend({
setupController: function(controller, category) {
controller.set('model', category);
},
serialize: function(model) {
return {
category_slug: model.get("name").toLowerCase()
};
}
});
This way you can remove also the slug computed property in your model, and in your links you then do:
{{#each model}}
{{#linkTo 'category' this}}{{name}}{{/linkTo}}
{{/each}}
Hope it helps.

How do I pass model information to this each statement in a nested template?

I have an index route where I need to populate a menu in one outlet based on a list of models. However I cannot get the models to be represented in the each statement.
Here is the Category Model:
App.Category = DS.Model.extend({
title: DS.attr('string'),
parent: DS.belongsTo('App.Category')
})
And here is the indexRoute where I render it
App.IndexRoute = Em.Route.extend({
renderTemplate: function(){
this.render('index')
this.render('categoryMenu',
{
outlet: 'sidebar',
into: 'index',
model: function() {
return App.Category.find()
},
controller: App.CategoriesController
})
this.render('badgesList',{
outlet: 'badgesList',
into: 'index'
})
}
})
Index Template:
<script type="text/x-handlebars" data-template-name="index">
<div class="span3">
{{outlet sidebar}}
</div>
<div class="span8">
{{outlet badgesList}}
</div>
</script>
Nested Category Template
<script type="text/x-handlebars" data-template-name="categoryMenu">
<ul>
{{#each model}}
{{title}}
{{/each}}
</ul>
</script>
I have tried to change the each statement to several different things like controller or item in model but nothing is displayed.
Thank you for any help!
Make yourself CategoriesController first like this:
App.CategoriesController = Ember.ArrayController.extend({
content: function () {
return App.Category.find()
}.property()
});
rename your template just to categories
<script type="text/x-handlebars" data-template-name="categories">
<ul>
{{#each model}}
{{title}}
{{/each}}
</ul>
</script>
in your index template replace {{outlet}} with {{render 'categoies'}}
<script type="text/x-handlebars" data-template-name="index">
<div class="span3">
{{render 'categoies'}}
</div>
<div class="span8">
{{outlet badgesList}}
</div>
</script>
as last thing remove the call rendering categoryMenu.

Ember.js template rendering

I'm possibly reading the docs wrong. Can someone please check out my gist and tell me why the invoices/index template is not rendering?
When I read the ember.js docs it states it should render
posts
↳posts/index
(invoices/index in my case). The invoices template renders however.
Handlebars:
<script type="text/x-handlebars" data-template-name="application">
<h1>Ember Committers</h1>
<nav>
{{#linkTo "index"}}Index{{/linkTo}}
{{#linkTo "about"}}About{{/linkTo}}
{{#linkTo "invoices"}}Invoices{{/linkTo}}
</nav>
{{ outlet }}
</script>
<script type="text/x-handlebars" data-template-name="invoices">
<h1>Invoices</h1>
</script>
<script type="text/x-handlebars" data-template-name="invoices/index">
<ul>
{{#each invoice in invoices }}
<li>{{#linkTo "show" invoice.id}}{{ invoice.id }}{{/linkTo }}</li>
{{/each }}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="invoices/show">
<p>Invoice - {{ name }}</p>
</script>
<script type="text/x-handlebars" data-template-name="phone">
<p>Contributor - {{ title }}</p>
</script>
<script type="text/x-handlebars" data-template-name="about">
<p>About {{ title }}</p>
</script>
<script type="text/x-handlebars" data-template-name="index">
<p>Index</p>
</script>
JavaScript:
<script type="text/javascript" defer>
var App = Ember.Application.create({
LOG_TRANSITIONS: true
});
App.ApplicationView = Ember.View.extend({
templateName: 'application'
});
App.Router.map(function () {
this.route("about");
this.resource("invoices", { path: "/invoices" }, function () {
this.resource("show", { path: "/:id" });
});
});
var invoices = [
{id: 1},
{id: 2}
];
App.AboutRoute = Ember.Route.extend({
setupController: function (controller) {
// Set the IndexController's `title`
controller.set('title', "My App");
}
});
App.InvoicesIndexController = Ember.ArrayController.extend({
invoices: invoices
});
</script>
You need to include an {{outlet}} tag in your invoices template. Since index and show are nested resources of invoices, their templates get rendered inside the outlet that you specify in the invoices template.
Take a look at the nested resources part of the Ember.js guide.

Emberjs rendering wrong template

I am working with EmberJs and can't figure out why the following code won't render the 'new' template. When I navigate to /shops, I get a list of shops and a create button linking to '/shops/new', but when I click create, the 'new' template isn't rendered and instead stays the same as 'shops'. I can navigate to each individual shop fine, just not new.
App.js
window.App = Ember.Application.create();
App.Router.reopen({
location: 'history'
});
// Router
App.Router.map(function() {
this.resource('shops', function() {
this.route('new');
});
this.resource('shop', { path: '/shops/:shop_id' });
});
App.ShopsRoute = Ember.Route.extend({
model: function() {
return App.Shop.find();
}
});
App.ShopsNewRoute = App.ShopsRoute.extend({
model: function() {
return App.Shop.createRecord();
},
setupController: function( controller, model ) {
return this._super(),
controller.set( 'content', model )
}
});
App.ShopsNewController = Ember.ObjectController.extend();
// Models
App.Store = DS.Store.extend({
revision: 11,
adapter: DS.RESTAdapter
});
App.Shop = DS.Model.extend({
name: DS.attr('string'),
body: DS.attr('string'),
});
Index.html
<!DOCTYPE html>
<html>
<head>
<title>Ember/Rails App</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= csrf_meta_tags %>
</head>
<body>
<script type="text/x-handlebars" data-template-name="application">
<div class="row">
<div class="twelve columns">
<h1>Ordr</h1>
<hr>
{{outlet}}
</div>
</div>
</script>
<script type="text/x-handlebars" data-template-name="shops/new">
<h2>New Shop</h2>
</script>
<script type="text/x-handlebars" data-template-name="shops">
{{#each shop in controller}}
{{#linkTo "shop" shop}} {{ shop.id }}{{/linkTo}}
{{/each}}
{{#linkTo 'shops.new'}}Create{{/linkTo}}
</script>
<script type="text/x-handlebars" data-template-name="shop">
<h2>{{name}}</h2>
<p>{{body}}</p>
</script>
</body>
</html>
The way you have set up your routes and templates, you are telling Ember that you want to navigate to shops.new and keep all the list of shops showing even while you are in shops.new.
If that is in fact the scenario that you want, all you need to do is add an {{outlet}} inside the shops template:
<script type="text/x-handlebars" data-template-name="shops">
{{#each shop in controller}}
{{#linkTo "shop" shop}} {{ shop.id }}{{/linkTo}}
{{/each}}
{{#linkTo 'shops.new'}}Create{{/linkTo}}
{{outlet}}
</script>
However, if that is not what you really intend, and you actually want the list of shops to be hidden when you transition to shops.new, then you will need to change a couple of things.
change your App.ShopsRoute to App.ShopsIndexRoute :
App.ShopsIndexRoute = Ember.Route.extend({
model: function() {
return this.store.find('shop');
}
});
and your shops template to shops/index template:
<script type="text/x-handlebars" data-template-name="shops/index">
{{#each shop in controller}}
{{#linkTo "shop" shop}} {{ shop.id }}{{/linkTo}}
{{/each}}
{{#linkTo 'shops.new'}}Create{{/linkTo}}
</script>
Any of those 2 methods should fix your problem, depending on what your intentions are.