Ember.js return the same model - javascript

I am creating an app in Rails and Ember.js. I have the following:
models/post.js
App.Post = DS.Model.extend({
title: DS.attr('string'),
param: DS.attr('string')
});
routes/posts.js
App.PostsIndexRoute = Em.Route.extend({
model: function() {
return this.store.findQuery('post');
}
});
// Esto hace falta?
App.PostsShowRoute = Em.Route.extend({
serialize: function(model) {
return {
post_id: model.get('param')
};
}
});
router.js
App.Router.reopen({
location: 'history'
});
App.Router.map(function() {
this.resource('posts', function() {
return this.route('show', {
path: '/:post_id'
});
});
});
store.js
App.Store = DS.Store.extend({
adapter: DS.RESTAdapter.reopen({
namespace: 'api'
})
});
templates/posts.hbs
{{outlet}}
template/posts/index.hbs
<ul>
{{#each controller}}
<li>{{#linkTo "posts.show" this}}{{title}}{{/linkTo}}</li>
{{/each}}
</ul>
When I visit localhost:3000/posts
I get a list with posts, my database has 7 posts, and in this view ember.js show 7(li) element but with the last post element.
My database has: post1, pos2, post3, post4, post5, post6, post7
View show: post7, post7,post7, post7, post7,post7,post7
Any idea?

I have added a field as id in models/post.js so post will be unique. And this solve my problem. Thanks.

Related

How to connect an Ember.js Controller to a View

I have the following structure in my Ember app:
App.Router.map(function() {
this.route('shop', { path: '/shop' });
});
App.ShopRoute = Ember.Route.extend({
model: function() {
return $.getJSON( "/fruits"); // this returns a json like this: { apples: [...], oranges: [...]}
}
});
App.AppleListItemView = Ember.View.extend({
templateName: 'apple-list-item',
tagName: 'li',
classNames: ['apple']
});
App.AppleListItemController = Ember.ArrayController.extend({
color: "green",
});
Next, when I try to use {{color}} in the apple-list-item template, it prints nothing. How should I fix this?
You need to worry about your naming. A shop route in your router, expects a ShopRoute and a ShopController, but we can leave that out ember will generate one for you. and a shop template. You should consider your view an optional extension of your template. Ember always has an index route so you need an index template:
<script type="text/x-handlebars" data-template-name="index">
{{#link-to 'shop'}}shop!{{/link-to}}
</script>
And a shop template with an itemController in the each adding a controller to each element in the apples list:
<script type="text/x-handlebars" data-template-name="shop">
SHOP! {{color}}
<ul>
{{#each apple in model.apples itemController='apple'}}
<li class="apple">{{apple.model}} {{apple.color}}</li>
{{/each}}
</ul>
</script>
And then your application would look somehting like:
App = Ember.Application.create();
App.Router.map(function() {
this.route('shop', { path: '/shop' });
});
With a ShopRoute:
App.ShopRoute = Ember.Route.extend({
model: function() {
return { apples: [ 'grannysmith', 'pinklady' ], oranges: [ 'clementines' ]};
}
});
And a AppleController to be used as itemController:
App.AppleController = Ember.Controller.extend({
color: function() {
if (this.get('model') === 'grannysmith') {
return 'green';
}
return 'purple';
}.property('model'),
});
See this jsbin.

Make a controllers model available to the ApplicationController before it's loaded in Ember

I am trying get access to a controller needed by my ApplicationController (Application needs Practice), however the PracticeController is only available after the resource has been loaded through it's respective route-url visit.
How, can I make sure the PracticeController and it's content/model is available at all times?
To be specific, I need my flashcardArray to be available throughout my application and at all times, even when the Practice-route hasn't been visited, thus loaded yet.
Thanks for any help!
Here is my code:
App.Router.map(function() {
this.resource('signup');
this.resource('login');
this.resource('profile');
this.resource('practice');
this.resource('overview');
});
App.ApplicationRoute = Ember.Route.extend({
model: function () {
return this.store.find('user');
}
});
App.LoginRoute = Ember.Route.extend({
controllerName: 'application',
model: function () {}
});
App.PracticeRoute = Ember.Route.extend({
model: function () {
return this.store.find('flashcards');
}
});
//ApplicationController
App.ApplicationController = Ember.ObjectController.extend({
needs: ['practice'],
flashcardArray: Ember.computed.alias('controllers.practice.flashcardArray'),
currentUser: Ember.computed.alias('model'),
isLoggedIn: false
}
});
//PracticeController
App.PracticeController = Ember.ObjectController.extend({
needs: ['application'],
flashcardArray: Ember.computed.alias('model'),
currentUser: Ember.computed.alias('controllers.application.currentUser')
}
});
// Practice template feeded into an outlet of the application template
<script type="text/x-handlebars" id="practice">
<div class="content-padded">
{{#each object in flashcardArray}}
<div class="card_wrapper">
<p><h1>{{{object.num_reference}}}</h1><p>
<p>PinYin: {{{object.mandarin}}}</p>
<p>def: {{object.definition}}</p>
{{/each}}
</div>
</script>
I think if you have data you need throughout the application, regardless of the user's active route, you probably need to return it as the ApplicationRoute:
App.ApplicationRoute = Ember.Route.extend({
model: function () {
return {
user: this.store.find('user'),
flashcards: this.store.find('flashcards')
};
}
});

ember.js using itemController with each helper doesnt work as expected

How should i change the following code to work as expected, so doesnt change the completedness of other todos if i completed one?
itemController="todo" claimed to wrap each item in an own controllers but fails to do so.
index.html
<script type="text/x-handlebars" id="todos">
<ul>
{{#each controller itemController="todo"}}
<li>{{#link-to 'todo' this}}{{job}} -- {{#if isCompleted}}Completed{{else}}Incomplete{{/if}}{{/link-to}}</li>
{{/each}}
</ul>
{{outlet}}
</script>
<script type="text/x-handlebars" id="todo">
<p>Job: {{job}} -- {{#if isCompleted}}Completed{{else}}Incomplete{{/if}}</p>
<button {{action 'complete' controller}}>Complete</button>
</script>
app.js
App = Ember.Application.create();
App.Router.map(function() {
this.resource('todos', function() {
this.resource('todo', { path: ':todo_id' })
});
});
App.IndexRoute = Ember.Route.extend({
redirect: function() { this.transitionTo('todos'); }
});
App.TodosRoute = Ember.Route.extend({
model: function() {
return todos;
}
});
App.TodoRoute = Ember.Route.extend({
model: function(params) {
return todos.findBy('id', params.todos_id);
}
});
App.TodosController = Ember.ArrayController.extend({
});
App.TodoController = Ember.ObjectController.extend({
isCompleted: false,
actions: {
complete: function() {
this.set('isCompleted',true);
}
}
});
var todos = [{id: '1', job: 'running'}, {id: '2', job: 'swimming'}, {id: '3', job: 'study'}];
I believe that you are mixing things
1 you have a list of todos each backed by ist own controller in the App.TodosRoute but in the App.TodoRoute you have another instance of the todoController, since the property is at the controller level, you are viewving the property setted for the 4th instance of the controller, the one reponsible for the todoRoute that is singleton.
You can move the property to the model and everything will goes well.
App.TodoController = Ember.ObjectController.extend({
actions: {
complete: function() {
this.set('isCompleted',true);
}
}
});
var todos = [{id: '1', job: 'running',isCompleted: false}, {id: '2', job: 'swimming',isCompleted: false}, {id: '3', job: 'study',isCompleted: false}];

Link tag dosen't work in Emberjs

This is model
App.Store = DS.Store.extend({
revision: 12,
adapter: DS.FixtureAdapter
});
App.Markets = DS.Model.extend({
ids: DS.attr("string"),
name: DS.attr("string"),
created: DS.attr("string")
});
App.Markets.FIXTURES = [
{ids:"312", name:"joy", created:"2012/1/1"},
{ids:"412", name:"adel", created:"2012/1/2"},
{ids:"512", name:"john", created:"2012/1/3"}
];
App.Sources = DS.Model.extend({
source_channel: DS.attr("string"),
handle: DS.attr("handle")
});
App.Sources.FIXTURES = [
{source_channel:"sc1", handle: "hn1"},
{source_channel:"sc2", handle: "hn2"}
];
This is route.
var App = Ember.Application.create();
App.Router.map(function() {
this.resource('markets', {path: '/markets'}, function() {
this.resource("sources", { path: "/:market_id" });
});
});
App.MarketsRoute = Ember.Route.extend({
model: function () {
return App.Markets.find();
}
});
App.SourcesRoute = Ember.Route.extend({
model: function(){
return App.Sources.find();
}
});
This is template
<script type="text/x-handlebars" id="_sources">
{{#each sources in content}}
<span>{{sources.handle}}</span>
<span>{{sources.sources_channel}}</span>
{{/each}}
</script>
<script type="text/x-handlebars" id="markets">
{{#each markets in content }}
{{#linkTo 'sources' markets.ids class="test" }}<span>Source</span>{{/linkTo}}
<span>{{markets.name}}</span>
<span>{{markets.created}}</span>
{{/each}}
<div class="sources">
{{partial "sources"}}
</div>
</script>
When I go to /#/markets, I can see the markets lists. This is correct.
Focus in {{#linkTo 'sources' markets.ids class="test" }}Source{{/linkTo}} of markets template.
In here, markets.ids doesn't work.
I'd like to go to /#/markets/markets_id when I click the link.
Along with passing the object to the sources route in linkTo,
define serialize method in your App.SourcesRoute.
The template:
{{#linkTo 'sources' markets class="test" }}<span>Source</span>{{/linkTo}}
The Route:
App.SourcesRoute = Ember.Route.extend({
model: function(){
return App.Sources.find();
},
serialize: function(model) {
return { market_id: model.ids };
}
});
You want to use linkTo 'sources' markets instead. ie:- pass the model in the each loop to the `linkTo.
Note: Regarding your naming conventions. Ember likes models to be singular, and Routes/Controllers plural or singular depending on whether the route points to one or more models.
Edit: Clarification.
Change the linkTo to this,
{{#linkTo 'sources' markets class="test" }}<span>Source</span>{{/linkTo}}

EmberJS nesting

Given the following code, I thought the person.index and nested person.finish routes would use the PersonController content/model property since theirs was empty/undefined? What am I doing wrong? http://jsfiddle.net/EasyCo/MMfSf/5/
To be more concise: When you click on the id, the {{id}} and {{name}} are blank? How do I fix that?
Functionality
// Create Ember App
App = Ember.Application.create();
// Create Ember Data Store
App.Store = DS.Store.extend({
revision: 11,
adapter: 'DS.FixtureAdapter'
});
// Create parent model with hasMany relationship
App.Person = DS.Model.extend({
name: DS.attr( 'string' ),
belts: DS.hasMany( 'App.Belt' )
});
// Create child model with belongsTo relationship
App.Belt = DS.Model.extend({
type: DS.attr( 'string' ),
parent: DS.belongsTo( 'App.Person' )
});
// Add Person fixtures
App.Person.FIXTURES = [{
"id" : 1,
"name" : "Trevor",
"belts" : [1, 2, 3]
}];
// Add Belt fixtures
App.Belt.FIXTURES = [{
"id" : 1,
"type" : "leather"
}, {
"id" : 2,
"type" : "rock"
}, {
"id" : 3,
"type" : "party-time"
}];
App.Router.map( function() {
this.resource( 'person', { path: '/:person_id' }, function() {
this.route( 'finish' );
});
});
// Set route behaviour
App.IndexRoute = Ember.Route.extend({
model: function() {
return App.Person.find();
},
renderTemplate: function() {
this.render('people');
}
});
Templates
<script type="text/x-handlebars">
<h1>Application</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" id="people">
<h2>People</h2>
<ul>
{{#each controller}}
<li>
<div class="debug">
Is the person record dirty: {{this.isDirty}}
</div>
</li>
<li>Id: {{#linkTo person this}}{{id}}{{/linkTo}}</li>
<li>Name: {{name}}</li>
<li>Belt types:
<ul>
{{#each belts}}
<li>{{type}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" id="person">
<h2>Person</h2>
Id from within person template: {{id}}<br><br>
{{outlet}}
</script>
<script type="text/x-handlebars" id="person/index">
Id: {{id}}<br>
Name: <a href="#" {{action "changeName"}}>{{name}}</a><br><br>
{{#linkTo index}}Go back{{/linkTo}}<br>
{{#linkTo person.finish}}Go to finish{{/linkTo}}
</script>
<script type="text/x-handlebars" id="person/finish">
<h2>Finish</h2>
{{id}}
</script>
You can use this in your router:
model: function() {
return this.modelFor("person");
}
Instead of your's:
controller.set('content', this.controllerFor('person'));
Your views were served through different controllers, either Ember's generated one or the one you defined PersonIndexController and that contributed to the issue you were facing. Instead of patching your original example to make it work, i instead reworked it to show you how you should structure your views/routes to leverage Emberjs capabilities.
You should design your application/example as a series of states working and communicating with each other and captured in a Router map. In your example, you should have a people, person resource and a finish route with corresponding views and controllers, either you explicitly create them or let Ember do that for you, providing you're following its convention.
Here's a working exemple and below I highlighted some of the most important parts of the example
<script type="text/x-handlebars" data-template-name="people">
<h2>People</h2>
<ul>
{{#each person in controller}}
<li>
<div class="debug">
Is the person record dirty: {{this.isDirty}}
</div>
</li>
<li>Id: {{#linkTo 'person' person}}{{person.id}}{{/linkTo}}</li>
<li>Name: {{person.name}}</li>
<li>Belt types:
<ul>
{{#each person.belts}}
<li>{{type}}</li>
{{/each}}
</ul>
</li>
{{/each}}
</ul>
</script>
<script type="text/x-handlebars" data-template-name="person">
<h2>Person</h2>
Id from within person template: {{id}}<br><br>
Id: {{id}}<br>
Name: <a href="#" {{action "changeName"}}>{{name}}</a><br><br>
{{#linkTo index}}Go back{{/linkTo}}<br>
{{#linkTo person.finish}}Go to finish{{/linkTo}}
{{outlet}}
</script>
Models, Views, Controllers and Route definitions
DS.RESTAdapter.configure("plurals", { person: "people" });
App.Router.map( function() {
this.resource('people',function() {
this.resource('person', { path: ':person_id' }, function() {
this.route( 'finish');
});
})
});
App.PeopleController = Ember.ArrayController.extend();
App.PeopleRoute = Ember.Route.extend({
model: function() {
return App.Person.find();
}
})
App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('people');
}
});
App.PersonRoute = Ember.Route.extend({
model: function(params) {
debugger;
return App.Person.find(params.client_id);
},
renderTemplate: function() {
this.render('person',{
into:'application'
})
}
})
App.PersonFinishRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('finish',{
into:'application'
})
}
})

Categories