ember js 'undefined' in url - ember.js

This is my menu bar code in html
<script type="text/x-handlebars" data-template-name="links">
<div class="navbar navbar-inverse navbar-fixed-top">
<ul class="nav nav-pills">
<li>{{#link-to "myleaves" 1255 action="myleavesinfolist"}}My Leave{{/link-to}}</li>
<li>{{#link-to "approvalrequests" 1255 action="appreqlist"}}Approval Requests{{/link-to}}</li>
<p class="navbar-text navbar-right"><button type="button" class="btn btn-info" {{action "logout"}}>Logout</button></p>
<p class="navbar-text navbar-right"><font color="white" size=4>Welcome {{model.userName}}</font></p>
</ul>
</div>
{{outlet}}
Here is my ember js code
App.Router.map(function () {
this.resource("signin", {path: "/"});
this.resource("links", {path: "/:id"},
function () {this.resource("myleaves",path: "/myleaves/:id"});
this.resource("approvalrequests", {path: "/appreq/:id"});
});
});
am bringing data by below code
App.LinksController = Ember.ObjectController.extend({
actions: {
myleavesinfolist: function () {
rdata = $.ajax({
type: "POST",
url: "/myleaves",
dataType: "json",
async: false
}).responseJSON;
this.transitionToRoute("myleaves", rdata);
} //myleavesinfolist
,
appreqlist: function () {
rdata = $.ajax({
type: "POST",
url: "/aprreq",
dataType: "json",
async: false
}).responseJSON;
final = filterData(rdata);
console.log(final);
this.transitionToRoute("approvalrequests", final);
} //appreqlist
} //actions
}); //controller
but when i click on menu link "myleaves " or "approval requests"
my url is like
http://localhost:8888/Leave.html#/undefined/myleaves/undefined
i dont knw why this undefined is coming..
PLease help
am a newbie

link-to expects a model object as its second argument, rather than an id.
So you’ll likely want to load the models for myleaves and approvalrequests earlier on—perhaps in your ApplicationRoute:
App.ApplicationRoute = Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
myLeaves: this.store.find('leaves'), // or however you fetch model data
approvalRequests: this.store.find('approval-request') // ditto
});
}
});
And the template becomes:
<script type="text/x-handlebars" data-template-name="links">
<div class="navbar navbar-inverse navbar-fixed-top">
<ul class="nav nav-pills">
<li>{{#link-to "myleaves" myLeaves action="myleavesinfolist"}}My Leaves{{/link-to}}</li>
<li>{{#link-to "approvalrequests" approvalRequests action="appreqlist"}}Approval Requests{{/link-to}}</li>
</ul>
<p class="navbar-text navbar-right"><button type="button" class="btn btn-info" {{action "logout"}}>Logout</button></p>
<p class="navbar-text navbar-right"><font color="white" size=4>Welcome {{model.userName}}</font></p>
</div>
{{outlet}}
</script>
EDIT
Based on your model code—and the fact that your requests don’t actually depend on the ID—I’d suggest the following:
App.Router.map(function () {
this.resource('signin', { path: '/' });
this.resource('links', { path: '/links' }, function() {
this.resource('my-leaves', { path: '/myleaves' });
this.resource('approval-requests', { path: '/appreq' });
});
});
function getJSONByPost(url) {
return $.ajax({
url: url,
type: 'POST',
dataType: 'json'
});
}
App.MyLeavesRoute = Ember.Route.extend({
model: function() {
return getJSONByPost('/myleaves');
}
});
App.ApprovalRequestsRoute = Ember.Route.extend({
model: function() {
return getJSONByPost('/aprreq');
}
});
Your template becomes:
<script type="text/x-handlebars" id="links">
<div class="navbar navbar-inverse navbar-fixed-top">
<ul class="nav nav-pills">
<li>{{#link-to "my-leaves"}}My Leaves{{/link-to}}</li>
<li>{{#link-to "approval-requests"}}Approval Requests{{/link-to}}</li>
</ul>
<p class="navbar-text navbar-right"><button type="button" class="btn btn-info" {{action "logout"}}>Logout</button></p>
<p class="navbar-text navbar-right"><font color="white" size=4>Welcome {{userName}}</font></p>
</div>
{{outlet}}
</script>
This is a bit of a departure from what you currently have. It’s hard to know the full structure and flow of your app without speaking directly. Nevertheless, I hope it’s of some use.

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: How do bindings work in the application template?

I have a boolean variable focusBool that hide the menu of the Web App when True. The Application template with the {{#if}} statement is below:
<script type="text/x-handlebars">
{{#if focusBool}}
<nav class="navbar navbar-default navbar-fixed-bottom" role="navigation">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Brand</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
{{#link-to 'home' tagName="li"}}
{{#link-to 'home'}}
Home
{{/link-to}}
{{/link-to}}
{{#link-to 'books' tagName="li"}}
{{#link-to 'books'}}
Books
{{/link-to}}
{{/link-to}}
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav
{{/if}}
<div class='container-fluid'>
{{outlet}}
</div>
</script>
This variable has been injected to all routes, controllers and components. When the focusBool is changed to true after the Application has loaded, the menu items do not disappear. How can I have the Application template be rerendered when the focusBool is modified? My understanding is that the {{#if focusBool}} would monitor when focusBool value change and show or hide the menu accordingly?
Here more related code:
App.Session = Ember.Object.extend({
user: null,
focusBool: false,
userID: '',
});
Injection:
Ember.Application.initializer({
name: 'login',
initialize: function (container, application) {
App.register('session:main', App.Session.create(), { instantiate: false, singleton: true });
// Add `session` object to route to check user
App.inject('route', 'session', 'session:main');
// Add `session` object to controller to visualize in templates
App.inject('controller', 'session', 'session:main');
// Add `session` object to session to visualize in templates
App.inject('component', 'session', 'session:main');
}
});
The Application Route:
App.ApplicationRoute = Ember.Route.extend({
isAutheticated: null,
actions: {
login: function() {
//var session = this.get('session.');
var isAuth = false;
var store = this.store;
var user = null;
var _this = this;
var firebase = new Firebase("https://dynamicslife.firebaseio.com");
firebase.authWithOAuthPopup('facebook', function(error, authData) {
if (error) {
isAutheticated = false;
console.log('failled login attempt', error);
} else if (authData) {
isAutheticated = true;
console.log('user authenticated with Firebase', authData.uid);
var record = store.find('user', authData.uid).then(function(_user) {
console.log('user exist in Firebase');
_this.session.set('userID', authData.uid);
//_this.rerender();
}, function(error) {
// user does not exist or some other error
store.unloadAll('user');
user = store.createRecord('user', {
id: authData.uid,
uid: authData.uid,
displayName: authData.facebook.displayName,
});
user.save();
_this.session.set('userID', authData.uid)
_this.rerender();
console.log('New user created in Firebase');
});
}
});
},
logout: function() {
var firebase = new Firebase("https://dynamicslife.firebaseio.com");
firebase.unauth();
isAuth = false;
this.session.set('userID', '');
console.log('logged out');
}
}
});
At first glance it seems your referencing focusBool incorrectly in the template. Since you're injecting the session object, you should reference it like session.focusBool in the template.
Here is a working demo.

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.

ember {{action}} doesn't work

I want button to call removeAlbum function in controller. But it does nothing. When i click the button nothing happens and there are no errors... What should i do to fix that?!
This is my template:
<script type="text/x-handlebars" data-template-name="albums">
{{#if App.albumsController.total}}
<div><h1>Количество альбомов: {{App.albumsController.total}}</h1></div>
{{#each content in App.albumsController}}
<div class='album'>
<div class='image'>
<a {{action showAlbum content href=true}}>
<img {{bindAttr src="content.avatarUrl"}}>
</a>
</div>
<div class='info'>
<h2>
<a {{action showAlbum content href=true}}>
{{content.title}}
</a>
</h2>
<div>{{content.description}}</div>
</div>
<div class='actions'>
<div>
<button {{action removeAlbum content target="App.albumsController"}}>Delete</button>
</div>
</div>
<div class='clear'></div>
</div>
{{/each}}
{{else}}
<div><h1>Loading</h1></div>
{{/if}}
</script>
This is my controller:
App.albumsController = Em.ArrayController.create({
content: [],
total: null,
loadAlbums: function(){
this.set('content', []);
this.set('total', null);
var self = this;
$.post(App.connection.url, {method: 'albums.getAll', params: {user_id: App.connection.userId}}, function(response){
self.set('total', response.albums.total);
response.albums.album.forEach(function(item){
var buf = App.AlbumInList.create({
id: item.id,
title: item.title,
description: item.description,
avatarUrl: item.thumbnail_video.thumbnails.thumbnail[1]._content
});
self.pushObject(buf);
});
});
},
removeAlbum: function(x){
console.log('remove it');
}
});
Try to set your target to controller instead of App.albumsController. Should solve the problem.
<button {{action removeAlbum content target="controller"}}>Delete</button>