template rendering is not working properly in ember js - ember.js

I am very new to Ember js. when i route one template to another it working properly.but the problem is when i was render same template it won't work.
My code is follows:
index.html:Manager template in index.html
<script type="text/x-handlebars" data-template-name="manager">
{{#each model.manager}}
<div class="pure-g-r content-ribbon">
<div class="pure-u-1-3">
<div class="img-viewer-profile">
<img {{bindAttr src="image"}}>
</div>
</div>
<div class="pure-u-2-3">
<div class="l-box">
<h4 class="content-subhead">{{name}}</h4>
<table class="pure-table">
<tbody>
<tr class="pure-table-odd">
<td>Id</td>
<td><b>ATL-{{id}}</b></td>
</tr>
<tr class="pure-table-odd">
<td>Team</td>
<td><b>{{team}}</b></td>
</tr>
<tr>
<td>Division</td>
<td><b>{{division}}</b></br>
</tr>
<tr class="pure-table-odd">
<td>Manager</td>
<td>
<b>
<a href="#" {{action "managerinfo" manager_id}}>
{{manager_name}}
</a>
</b>
</td>
</tr>
{{/each}}
<tr>
<td>Reportees</td>
<td>
{{#each model.results}}
<br><b>
<a href="#" {{action "profileinfo" id}}>
{{reportees}}
</a>
</b></br>
{{/each}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
{{outlet}}
</script>
app.js:
=========
App.ManagerController = Ember.ObjectController.extend({
manager_id: '',
id: '',
actions:{
managerinfo: function(manager_id) {
// the manager id of selected manager field
var manager_id = manager_id;
alert("profile");
alert(manager_id);
managerdata = $.ajax({
dataType: "json",
url: "/manager?manager_id=" + manager_id,
async: false}).responseJSON
managerdata.manger_id = manager_id;
console.log(managerdata);
this.transitionToRoute('manager', managerdata);
}
)}
Now my problem is when render the new manager data to manager it wont be displayed.
After refresh only it shows the data.
what mistake i was done in this code , i dont understand.so please provide me solution.
i added my complete code here with proper tags order.

As per your comment, the way you are doing is not suggested. You can pass manager_id in the route url. I will give you very basic skeleton which you can make further changes. Do remember, if you want to set model data from ajax, use model hook in the route
First Router
App.Router.map(function() {
this.resource("managers", function(){
this.route("all");
this.route("manager", { path: "/:manager_id" });
});
});
So here with #/manager/all displays all managers list
#/manager/:manager_id displays manager with id manager_id
Next ManagerAll route
App.ManagersAllRoute = Ember.Route.extend({
model: function() {
//do ajax and return managers data which sets as model for this route
}
});
sameway
App.ManagersManagerRoute = Ember.Route.extend({
model: function(params) {
//do ajax and return managers data which sets as model for this route
//here params will have the manager_id passed through url
//as it is ajax, create a promise
return new Ember.RSVP.Promise(function(resolve, reject) {
Ember.$.ajax({
dataType: "json",
url: "/manager?manager_id=" + params.manager_id,
async: false}).then(function(data){
resolve(data);
})
});
}
});
Next is template for managers
{{#each model.manager}}
{{#link-to 'managers.manager' manager_id}}{{{manager_name}}{{/link-to}}
{{/each}}
Now a template for manager
{{manager_id}}
{{manager_name}} blah blah blah

You didn't close the each tag properly.
<script type="text/x-handlebars" data-template-name="manager">
{{#each model.manager}}
<a href="#" {{action "managerinfo" manager_id}}>
{{manager_name}}
</a>
{{/each}}
</script>
Also you haven't closed the ManagerController correctly in the given above. Double check that.
App.ManagerController = Ember.ObjectController.extend({
manager_id: '',
id: '',
actions:{
managerinfo: function(manager_id) {
// the manager id of selected manager field
var self=this;
var manager_id = manager_id;
alert("profile");
alert(manager_id);
managerdata = $.ajax({
dataType: "json",
url: "/manager?manager_id=" + self.manager_id,
async: false}).responseJSON.then(function(managerdata) {
managerdata.manger_id = self.manager_id;
console.log(managerdata);
this.transitionToRoute('manager', managerdata);
})
}
)}

Related

Ember CRUD application

Hello I am trying to develop stock list data along with CRUD application for assignment purpose but only stock list data is getting displayed. Here is my code. Its not displaying the other part (i.e. CRUD part) and its not showing any error as well. I am very new to ember I think it might be some silly mistake but I've tried lot of stuff but I am lost as its not throwing any error. I am not looking or any backed neither I am planning to save data. I just want to show CRUD functionality of EMBER.js some thing like this of angular
Here is my HTML
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Ember.js</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<!-- EmberJS dependencies -->
<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="http://builds.handlebarsjs.com.s3.amazonaws.com/handlebars-v1.3.0.js"></script>
<script src="http://builds.emberjs.com/tags/v1.8.1/ember.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.0.0-beta.11/ember-data.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/ember-localstorage-adapter/0.3.1/localstorage_adapter.js"></script>
<!-- Lightstreamer JavaScript Client library -->
<script src="http://cdnjs.cloudflare.com/ajax/libs/require.js/2.1.9/require.min.js"></script>
<script src="http://demos.lightstreamer.com/commons/lightstreamer.js"></script>
<!-- EmberJS code application -->
<script src="js/stockListDemoApp.js"></script>
<!-- Bootstrap -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css">
</head>
<body>
<script type="text/x-handlebars" data-template-name="stock">
<div id="wrap">
<div id="top">
<a id="logoEmber" href="http://emberjs.com" target="_blank"><img src="images/ember_logo.png" alt="EMBERLOGO" hspace="0" border="0" /></a>
<div id="title">STOCK-LIST</div>
</div>
<table cellspacing="0" cellpadding="2" width="780" border="0" >
<thead>
<tr class="tableTitle">
<td>Name</td>
<td>Last</td>
<td>Time</td>
<td>Change</td>
<td>Bid Size</td>
<td>Bid</td>
<td>Ask</td>
<td>Ask Size</td>
<td>Min</td>
<td>Max</td>
<td>Ref.</td>
<td>Open</td>
</tr>
</thead>
<tbody>
{{#each item in model}}
<tr {{bind-attr class="item.isOdd:colOdd:colEven"}}>
<td><div {{bind-attr class="item.isOdd:stockNameOdd:stockNameEven"}}>{{item.stock_name}}</div></td>
<td>{{item.last_price}}</td>
<td>{{item.time}}</td>
<td>{{item.pct_change}}</td>
<td>{{item.bid_quantity}}</td>
<td>{{item.bid}}</td>
<td>{{item.ask}}</td>
<td>{{item.ask_quantity}}</td>
<td>{{item.min}}</td>
<td>{{item.max}}</td>
<td>{{item.ref_price}}</td>
<td>{{item.open_price}}</td>
</tr>
{{/each}}
</tbody>
</table>
<div class="disc">Simulated market data.</div>
</div>
</br>
</br>
<script type="text/x-handlebars" data-template-name="index">
<div class="jumbotron">
<h1>Welcome!</h1>
<p>This app demonstrates CRUD with validation in Ember.js</p>
</div>
</script>
<script type="text/x-handlebars" data-template-name="products">
<h1>Products</h1>
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="products/index">
<table id="products_table" class="table">
<thead>
<tr>
<th>Name</th>
<th>Author</th>
<th>Price</th>
<th><button type="button" class="btn btn-default new-button" {{action "new"}}><span class="glyphicon glyphicon-plus"></span></button></th>
</tr>
</thead>
<tbody>
{{#each product in model}}
<tr {{bind-attr id=product.htmlID}}>
<td class="name">{{#link-to "products.show" product}}{{product.name}}{{/link-to}}</td>
<td class="author">{{product.author}}</td>
<td class="price">{{product.price}}</td>
<td class="action-buttons"><button type="button" class="btn btn-default edit-button" {{action "edit" product}}><span class="glyphicon glyphicon-pencil"></span></button>
<button type="button" class="btn btn-default delete-button" {{action "delete" product}}><span class="glyphicon glyphicon-remove"></button></td>
</tr>
{{/each}}
</tbody>
</table>
<p id="products_count">Total: {{controllers.products.productsCount}} products.</p>
</script>
<script type="text/x-handlebars" data-template-name="products/show">
<h2><span class="name">{{name}}</span></h2>
<p>By <span class="author">{{author}}</span></p>
<p><strong>$<span class="price">{{price}}</span></strong></p>
<p><span class="description">{{description}}</span></p>
<p class="action-buttons"><button type="button" class="btn btn-default edit-button" {{action "edit" model}}><span class="glyphicon glyphicon-pencil"></span></button>
<button type="button" class="btn btn-default delete-button" {{action "delete" model}}><span class="glyphicon glyphicon-remove"></button></p>
<p>{{#link-to 'products' class="index-link"}}Back to products index{{/link-to}}</p>
</script>
<script type="text/x-handlebars" data-template-name="products/edit">
<h2>{{#if isNew}}New{{else}}Edit{{/if}} Product</h2>
{{#form-for controller id="form-product" wrapper="bootstrap"}}
{{#input name}}
{{label-field name text="Product"}}
{{input-field name class="form-control" autofocus="true"}}
{{#if view.showError}}
{{error-field name}}
{{/if}}
{{/input}}
{{#input author}}
{{label-field author text="Author"}}
{{input-field author class="form-control"}}
{{#if view.showError}}
{{error-field author}}
{{/if}}
{{/input}}
{{#input description}}
{{label-field description text="Description"}}
{{input-field description class="form-control"}}
{{#if view.showError}}
{{error-field description}}
{{/if}}
{{/input}}
{{#input price}}
{{label-field price text="Price"}}
{{input-field price class="form-control"}}
{{#if view.showError}}
{{error-field price}}
{{/if}}
{{/input}}
<button type="submit" class="btn btn-primary save-button" {{action "save" model}}>Save</button>
{{#if isNew}}
<button type="button" class="btn btn-default cancel-button" {{action "delete" model}}>Cancel</button>
{{else}}
<button type="button" class="btn btn-default cancel-button" {{action "cancel" model}}>Cancel</button>
<button type="button" class="btn btn-danger delete-button" {{action "delete" model}}>Delete</button>
{{/if}}
{{/form-for}}
</script>
</script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.0.0-beta.8/ember-data.min.js"></script>
<!-- ember-easyForm -->
<script src="http://builds.dockyard.com.s3.amazonaws.com/ember-easyForm/canary/shas/add6a40a68c8b081557a9011cf99ea255414e1b1/ember-easyForm.min.js"></script>
<!-- ember-validations -->
<script src="http://builds.dockyard.com.s3.amazonaws.com/ember-validations/canary/shas/2ff28c6ba4d227b0f863b327cdff23c381c37afb/ember-validations.min.js"></script>
</body>
</html>
and here is my app.js
App = Ember.Application.create();
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return $.getJSON('https://ajax.googleapis.com/ajax/services/feed/load?' +
'v=1.0&num=50&q=https://news.google.com/news/feeds?output=rss&callback=?')
.then(function(data){
return data.responseData.feed.entries.map(function(entry){
var post = {};
post.title = entry.title;
return post;
});
});
}});
window.App = Ember.Application.create();
App.ApplicationAdapter = DS.FixtureAdapter.extend({
namespace: 'ember-crud'
});
Ember.EasyForm.Config.registerWrapper('bootstrap', {
formClass: '',
fieldErrorClass: 'has-error',
inputClass: 'form-group',
errorClass: 'help-block error',
hintClass: 'help-block',
labelClass: ''
});
App.Router.map(function() {
this.resource('products', function() {
this.route('new');
this.route('show', {path: '/:product_id'});
this.route('edit', {path: '/:product_id/edit'});
});
});
App.Product = DS.Model.extend(Ember.Validations.Mixin, {
name: DS.attr('string'),
author: DS.attr('string'),
description: DS.attr('string'),
price: DS.attr('number'),
// To identify html tag for a Product.
htmlID: function() {
return 'product' + this.get('id');
}.property('id'),
validations: {
name: {
presence: true
},
price: {
presence: true,
numericality: {
greaterThanOrEqualTo: 0
}
}
}
});
App.resetFixtures = function() {
App.Product.FIXTURES = [
{
id: 1,
name: 'Ember.js in Action',
author: 'Joachim Haagen Skeie',
description: 'Ember.js in Action is a crisp tutorial that introduces the Ember.js framework and shows you how to build production-quality web applications.',
price: 44.99
},
{
id: 2,
name: 'Building Web Applications with Ember.js',
author: 'Jesse Cravens & Thomas Brady',
description: 'This guide provides example-driven instructions on how to develop applications using Ember, one of the most popular JavaScript frameworks available.',
price: 29.99
},
{
id: 3,
name: 'The Ember.js Way',
author: 'Brian Cardarella & Alex Navasardyan',
description: "Inspired by Addison-Wesley's classic The Rails Way series, The Ember.js Way crystallizes all that's been learned about Ember.js development into a start-to-finish approach that works.",
price: 39.99
},
{
id: 4,
name: 'Instant Ember.JS Application Development: How-to',
author: 'Marc Bodmer',
description: 'A practical guide that provides you with clear step-by-step examples. The in-depth examples take into account the key concepts and give you a solid foundation to expand your knowledge and your skills.',
price: 20.69
}
];
};
App.resetFixtures();
App.ProductsRoute = Ember.Route.extend({
model: function() {
return this.store.find('product');
},
actions: {
// Redirect to new form.
new: function() {
this.transitionTo('products.new');
},
// Redirect to edit form.
edit: function(product) {
this.transitionTo('products.edit', product);
},
// Save and transition to /products/:product_id only if validation passes.
save: function(product) {
var _this = this;
product.validate().then(function() {
product.save();
_this.transitionTo('products.show', product);
});
},
// Roll back and transition to /products/:product_id.
cancel: function(product) {
product.rollback();
this.transitionTo('products.show', product);
},
// Delete specified product.
delete: function(product) {
product.destroyRecord();
this.transitionTo('products');
}
}
});
App.ProductsController = Ember.ArrayController.extend({
productsCount: function() {
return this.get('model.length');
}.property('#each')
});
App.ProductsIndexRoute = Ember.Route.extend({
model: function() {
return this.modelFor('products');
}
});
App.ProductsIndexController = Ember.ArrayController.extend({
needs: ['products'],
sortProperties: ['name']
});
App.ProductsEditRoute = Ember.Route.extend({
model: function(params) {
return this.store.find('product', params.product_id);
},
// Roll back if the user transitions away by clicking a link, clicking the
// browser's back button, or otherwise.
deactivate: function() {
var model = this.modelFor('products.edit');
if (model && model.get('isDirty') && !model.get('isSaving')) {
model.rollback();
}
}
});
App.ProductsNewRoute = Ember.Route.extend({
model: function() {
return this.store.createRecord('product');
},
isNew: true,
renderTemplate: function(controller, model) {
this.render('products.edit', {
controller: controller
});
},
// Roll back if the user transitions away by clicking a link, clicking the
// browser's back button, or otherwise.
deactivate: function() {
var model = this.modelFor('products.new');
if (model && model.get('isNew') && !model.get('isSaving')) {
model.destroyRecord();
}
}
});

Ember didInsertElement on new elements

I have a topic list that receive a bootstrap popover event on page load.
But when I add new topics to this list without reload page I can't bind popover event in this new topic.
My code is organized in this way:
Forum route:
export default Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
run: this.store.find('run', this.modelFor('dialogo.admin.manager').get('id')),
topics: this.store.find('topic', { run: this.modelFor('dialogo.admin.manager').get('id') })
});
},
setupController: function (controller, model) {
controller.set('runID', this.modelFor('dialogo.admin.manager').get('id'));
controller.set('model', model.topics);
controller.set('currentRun', model.run);
}
});
Forum Controller:
export default Ember.Controller.extend({
needs: ['application'],
activeUser: Ember.computed.alias("controllers.application.model"),
actions: {
createTopic: function() {
var
store = this.get('store'),
user = this.get('activeUser'),
run = this.get('currentRun'),
topic;
topic = store.createRecord('topic', {
content: '',
run: run,
moderator: user
});
this.set('newTopic', topic);
},
saveNewTopic: function() {
var newTopic = this.get('newTopic');
var topicList = this.get('model');
newTopic.save().then(function(topic){
topicList.pushObject(topic);
Ember.$('#newTopic').modal('hide');
});
},
deleteTopic: function (topic) {
topic.destroyRecord();
}
}
});
Forum View:
export default Ember.View.extend({
didInsertElement: function() {
this.$('[data-toggle="popover"]').popover({
html : true,
content: function() {
var delID = Ember.$(this).attr('data-del');
return Ember.$('#alertDel' + delID).html();
}
});
}
});
Forum Template:
<tbody>
{{#each topic in model}}
<tr>
<th scope="row">{{topic.id}}</th>
<td>{{topic.content}}</td>
<td>{{topic.posts.length}}</td>
<td>0</td>
<td>
<button class="btn btn-default" type="button" data-toggle="popover" data-placement="top" data-trigger="focus" data-del="{{topic.id}}" title="ATENÇÃO: Deletar tópico">
DEL
</button> |
<span>EDIT</span> |
<span>PEND</span> |
<span>MOD</span>
<div id="alertDel{{topic.id}}" style="display: none;">
Você deseja deletar o tópico #ID {{topic.id}}?
Essa ação não poderá ser desfeita.
<br><br>
<button class="btn btn-danger" {{action 'deleteTopic' topic}}>Sim</button> |
<button class="btn btn-default">Não</button>
</div>
</td>
</tr>
{{else}}
<tr>
<td rowspan="5">Nenhum tópico encontrado...</td>
</tr>
{{/each}}
</tbody>
So, when I execute saveNewTopic and add this new topic to topicList, I lost my popover event.
Anyone have a clue about how can I bind my popover event on new topic instances?
You can refer to ember cookbook on how to handle bootstrap pop over, which the best way would be creating a component or rendering from router with an action.
http://guides.emberjs.com/v1.10.0/cookbook/user_interface_and_interaction/using_modal_dialogs/
App.ApplicationRoute = Ember.Route.extend({
actions: {
showPopUp: function(name, content){
//the controller for will help you let you access the content from your controller (if using a component)
this.controllerFor(name).set('content', content);
this.render(name, {
into: 'application',
outlet: 'popup'
});
},
removePop: function(){
this.disconnectOutlet({
outlet: 'popup',
parentView: 'application'
});
}
}
}
});
In your main application.hbs you need to add the pop up outlet
<setion id="main-content">
{{ outlet }}
</section>
<section id="footer-scroll">
{{partial "partials/footer"}}
</section>
{{outlet 'popup'}}
You would trigger the show pop up event like this
<a href="#" {{action 'showPopUp' 'select-country-pop' this}} class="cl-7 footer-text-desk ft-w-600">
In your forum template you can use it the same way
<button class="btn btn-default" type="button" data-del="{{topic.id}}" title="ATENÇÃO: Deletar tópico" {{action 'showPopUp' 'popuptemplate' this}}>
DEL
</button>
You need to create the pop up template, for your sanity it would be easier if you create a component
"this", just means it would inherit the data from your model

How should I handle an errors from server in Ember.js?

I have a small app, written using ember.js, that talks to REST API using RESTAdapter and displaying elements in list using ArrayController. When I'm performing a POST request to server and the responds with code 201 (Created) and a model with id the new models is displayed in list. But if server returns code 409 (Conflict) with the payload that looks like this
{
'errors': ['Error description']
}
I expect that model will not be added to list, but it isn't so. The model is still added to list, but without ID.
I found out that this model can be removed in multiple ways, but I don't know which of them is right.
So the questions are:
What is the right way to handle errors in this case (when you are using ArrayController and RESTAdapter)?
Is it possible to prevent model showing up in list if server returns 4xx code?
Here is code that I use now:
App.Usergroup = DS.Model.extend({
name: DS.attr('string'),
description: DS.attr('string'),
});
App.UsergroupsListController = Ember.ArrayController.extend({
needs: ['usergroups'],
allUsergroups: Ember.computed.alias('controllers.usergroups'),
itemController: 'usergroup'
});
App.UsergroupController = Ember.ObjectController.extend({
actions: {
removeGroup: function() {
var group = this.get('model');
group.deleteRecord();
group.save();
}
}
});
App.UsergroupsController = Ember.ArrayController.extend({
actions: {
addUsergroup: function() {
var model = this.get('model');
var group = this.store.createRecord('usergroup', {
name: model.name,
description: model.description
});
group.save().then(function() {
},
function(error){
group.rollback();
});
this.transitionTo('usergroups.index');
}
}
});
And here is the template excerpt:
<script type="text/x-handlebars" id="usergroups">
<div class="header">
<h1>User groups list</h1>
</div>
<div class="content">
<form class="pure-form">
<fieldset>
{{input valueBinding="model.name" placeholder="Name"}}
{{input valueBinding="model.description" placeholder="Description"}}
<button type="submit" {{action 'addUsergroup'}} class="pure-button pure-button-primary">Add</button>
</fieldset>
</form>
{{outlet}}
</div>
</script>
<script type="text/x-handlebars" id="usergroups-list">
{{#if model}}
<table class="pure-table pure-table-striped">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Description</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{{#each}}
<tr>
<td>{{id}}</td>
<td>{{name}}</td>
<td>{{description}}</td>
<td><button class="pure-button" {{action "removeGroup"}}><i class="fa fa-trash"></i> Remove</button></td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<p>No user groups.</p>
{{/if}}
</script>
Ember provides an error route and a loading route
Read more about it here - Ember error route
So when the Usergroup model throws an error, Ember will look for UsergroupErrorRoute or
usergroup/error template.
What you can do is you can have
<script type="text/x-handlebars" data-template-name="usergroup/error">
{{message}}
<script>
where {{message}} is transferred from the route
So, as I found out, errors should be handled in Route.
Currently my route looks like this:
App.UsergroupsRoute = App.AuthenticatedRoute.extend({
model: function() {
return this.store.find('usergroup');
},
redirectToLogin: function(transition) {
var loginController = this.controllerFor('login');
loginController.set('attemptedTransition', transition);
this.transitionTo('login');
},
actions: {
error: function(reason, transition) {
if (reason.status == 401) {
this.redirectToLogin(transition);
}
else {
alert('Something went wrong');
}
}
}
});
It works just fine and does what it should. But now I cannot get what is a reason for placing errors handling in Route?

Emberjs adding objects to ArrayController, server query is immutable

I'm trying to add objects to my Emberjs Arraycontroller. I have a "create" action that fires when a button is pushed. This works fine but I can't seem to add the element with the this.pushObject function to the ArrayController. I get this error message:
Uncaught Error: The result of a server query (on App.Software) is immutable.
I guess this is because I'm using the RESTAdapter to load data and it does not like that I'm adding elements manually?
Here is my controller and the create action.
App.SoftwareIndexController = Ember.ArrayController.extend({
sortProperties: ['revision'],
create:function(){
var revision = $('#software_revision').val();
var doc = $('#software_document').val();
var software = App.Software.createRecord({
product_id: 1,
revision: revision,
doc: doc
});
this.pushObject(software);
}
});
Here is the route
App.SoftwareIndexRoute = Ember.Route.extend({
setupController:function(controller){
var product_id = 1;
controller.set('content', App.Software.find({product_id:1}));
}
});
Here is the model and store
App.Store = DS.Store.extend({
revision: 12,
adapter: 'DS.RESTAdapter'
});
DS.RESTAdapter.configure("plurals", {
software: "software"
});
App.Software = DS.Model.extend({
revision: DS.attr('string'),
doc: DS.attr('string'),
verified: DS.attr('boolean')
});
And here is the template view with the create form and list of software
<script type="text/x-handlebars" data-template-name="software/index">
<p>
<fieldset>
<legend>Create a new software revision</legend>
<label for="software_revision">Revision</label>
<input id="software_revision" name="software_revision" type="text" placeholder="">
<label for="software_document">Document ID</label>
<input id="software_document" name="software_document" type="text" placeholder="">
<button class="btn btn-success" {{action create}}>Create</button>
</fieldset>
</p>
{{#if length}}
<table class="table">
<thead>
<tr>
<th>Revision</th>
<th>Created</th>
</tr>
</thead>
<tbody>
{{#each controller}}
<tr>
<td>{{revision}}</td>
<td>{{createdAt}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert">×</button>
<strong>No software revisions found!</strong> start by creating a new revision above.
</div>
{{/if}}
</script>
Does anybody know the proper way to add new object to a ArrayController store? Thank you!
This works by the way if I change the route so it doesn't use the RESTAdapter
App.SoftwareIndexRoute = Ember.Route.extend({
setupController:function(controller){
var product_id = 1;
controller.set('content', []); // not using the RESTAdapter to load data
}
});
I had this same problem. It looks like the content returned from App.Software.find() is an immutable array. I was able to get around this by getting the content of the immutable array which returned a mutable array.
For example:
In ember 1.0.0 + ember data 1.0.0 beta 3:
this.store.find('software').then(function (softwares) {
controller.set('content', softwares.get('content'));
});
And this is only a guess but for the version you were working with at the time of your post:
controller.set('content', App.Software.find().get('content'));

How to keep the url hash when adding pagination to an ember.js web app

I have a simple web app with a table that shows an array of users. The html for this is a basic table showing username / etc
The jsfiddle is here (though when you click the links to paginate jsfiddle seems to reload the page -not what I get locally when I copy/paste the below). But either way it helps show the basic app in action http://jsfiddle.net/Jmj4F/
<script type="text/x-handlebars" data-template-name="application">
<div id="main">
{{ outlet }}
</div>
</script>
<script type="text/x-handlebars" data-template-name="person">
<table width="250px">
<thead>
<th>id</th>
<th>username</th>
<th>update</th>
<th>delete</th>
</thead>
<tbody>
{{#each person in controller}}
<tr>
<td>{{person.id}}</td>
<td>{{view Ember.TextField valueBinding="person.username"}}</td>
<td><input type="submit" value="update" {{action updatePerson person}}/></td>
<td><input type="submit" value="delete" {{action removePerson person}}/></td>
</tr>
{{/each}}
</tbody>
</table>
<div id="pages">
Page.
2
3
</div>
</script>
​
My app currently has 2 routes -one that pushes the default view with every user. The second is a simple page route that should slice the array and only show a subset of the users (basic pagination)
PersonApp = Ember.Application.create({});
PersonApp.ApplicationController = Ember.ObjectController.extend({});
PersonApp.ApplicationView = Ember.View.extend({
templateName: 'application'
});
PersonApp.PersonView = Ember.View.extend({
templateName: 'person',
addPerson: function(event) {
var username = event.context.username;
if (username) {
this.get('controller.target').send('addPerson', username);
event.context.set('username', '');
}
}
});
PersonApp.Person = Ember.Object.extend({
username: null
});
PersonApp.PersonController = Ember.ArrayController.extend({
content: [],
page: function(page) {
//in a real app use the page # to slice the array
var newContent = this.content.slice(1,2);
this.set('content', newContent);
}
});
PersonApp.Router = Ember.Router.create({
root: Ember.Route.extend({
index: Ember.Route.extend({
route: '/',
connectOutlets: function(router) {
var first = PersonApp.Person.create({ username: "first" });
var middle = PersonApp.Person.create({ username: "middle" });
var last = PersonApp.Person.create({ username: "last" });
var people = [first,middle,last];
router.get('applicationController').connectOutlet('person', people);
}
}),
page: Ember.Route.extend({
route: '/page/:number',
deserialize : function (router, params) {
var pageNumber = params.number;
router.get('personController').page(pageNumber);
}
})
})
});
$(function () {
PersonApp.initialize(PersonApp.Router);
});
​
Currently when I click the 2 I see the hash in the url changes from
http://localhost:8000/#/page/2
to
http://localhost:8000/#/page/undefined
This example is still very hello world so I'm open to any improvements here. I'd like to use the router based approach just because it has back button support and that's a plus
Thank you in advance
UPDATE
I finally have a fully paginated / filter / sortable array controller (jsfiddle)
Looks like I just needed to add a serialize method -now I get the page # instead of undefined
serialize: function(router, context) {
return {
number: context.get('number')
}
}
The only problem with adding this is that context is undefined so I get the following error. What should this method look like?
Uncaught TypeError: Cannot call method 'get' of undefined