mardi 24 février 2015

How to use computed property of "needed" controller in Ember.js?

Let's say I want to build a small shop with two different product types fruits and vegetables. Each have a own page in my shop, what are separated routes, controllers and models for each. For both product categories I want to calculate the sum of 'ordered' items.


On a third page, called 'totals', I want to display both sums (fruit and vegetables) and the total sum of both. Therefore I am loading the two controllers of the product types like so: needs: ['BasketsFruits', 'BasketsVegetables'].


Question: Why are the sums of fruits and vegetables not updated on the totals-page when I change the quantity of items on the other pages? Is my general approach right?


Example: Everything working except the sum on the totals-page. Example in a jsbin





$(function () {
App = Em.Application.create();

App.ApplicationAdapter = DS.FixtureAdapter.extend();

App.ApplicationController = Em.Controller.extend();

App.BasketsFruitsController = Ember.ArrayController.extend({
totalSum: function() {
var sum = 0;
this.forEach( function (entry) {
sum += parseInt(entry.get('quant'));
});
return sum;
}.property('@each.quant')
});

App.BasketsVegetablesController = Ember.ArrayController.extend({
totalSum: function() {
var sum = 0;
this.forEach( function (entry) {
sum += parseInt(entry.get('quant'));
});
return sum;
}.property('@each.quant')
});

App.BasketsTotalsController = Ember.ObjectController.extend({
needs: ['BasketsFruits', 'BasketsVegetables'],
fruits: Ember.computed.alias("controllers.BasketsFruits.totalSum"),
vegetables: Ember.computed.alias("controllers.BasketsVegetables.totalSum")
});

App.Fruits = DS.Model.extend({
title: DS.attr('string'),
color: DS.attr('string'),
quant: DS.attr('int')
});

App.Vegetables = DS.Model.extend({
title: DS.attr('string'),
season: DS.attr('string'),
quant: DS.attr('int')
});

App.Fruits.FIXTURES = [
{
id: 1,
title: 'Banana',
color: 'yellow',
quant: 0
},
{
id: 2,
title: 'Apple',
color: 'red',
quant: 0
},
{
id: 3,
title: 'Melon',
color: 'green',
quant: 0
}
];

App.Vegetables.FIXTURES = [
{
id: 1,
title: 'Asparagus',
season: 'spring',
quant: 0
},
{
id: 2,
title: 'Pumpkin',
season: 'fall',
quant: 0
},
{
id: 3,
title: 'Cabbage',
season: 'winter',
quant: 0
}
];

App.Router.map(function() {
this.resource('index', { path: '/' });
this.resource('baskets', { path: 'baskets' } , function() {
this.route('index', { path: '/' });
this.route('fruits', { path: 'fruits' });
this.route('vegetables', { path: 'vegetables' });
this.route('totals', { path: 'totals' });
});
});


App.IndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('baskets');
}
});

App.BasketsIndexRoute = Ember.Route.extend({
redirect: function() {
this.transitionTo('baskets.fruits');
}
});

App.BasketsFruitsRoute = Ember.Route.extend({
model: function() {
return this.store.find('Fruits');
},
renderTemplate: function() {
this.render('fruits');
}
});

App.BasketsVegetablesRoute = Ember.Route.extend({
model: function() {
return this.store.find('Vegetables');
},
renderTemplate: function() {
this.render('vegetables');
}
});

App.BasketsTotalsRoute = Ember.Route.extend({
renderTemplate: function() {
this.render('totals');
}
});

});



a {
cursor: pointer;
}
.nav-tabs>li {
display: inline-block;
border: 1px solid black;
border-bottom: none;
margin: 2px 2px 0 0;
padding: 2px;
}
.nav-tabs>li.active {
color: white;
background-color: black;
}
.nav-tabs {
border-bottom: 1px solid black;
}
#main {
border: 1px solid black;
padding: 5px;
}



<script type="text/x-handlebars" data-template-name="application">
<ul class="nav nav-tabs">
{{#link-to "baskets.fruits" class="button" tagName="li"}}
<a {{bind-attr href="view.href"}}>Fruit Basket</a>
{{/link-to}}

{{#link-to "baskets.vegetables" class="button" tagName="li"}}
<a {{bind-attr href="view.href"}}>Vegetable Basket</a>
{{/link-to}}

{{#link-to "baskets.totals" class="button" tagName="li"}}
<a {{bind-attr href="view.href"}}>Totals</a>
{{/link-to}}
</ul>

<div id="main">
{{outlet}}
</div>
</script>

<script type="text/x-handlebars" data-template-name="fruits">
Select your fruits:
<ul>
{{#each item in model}}
<li>
{{item.title}} ({{item.color}})
{{input
type="number"
step="1"
placeholder="0"
value=item.quant
}}
</li>
{{/each}}
</ul>
You have {{totalSum}} fruits.
</script>

<script type="text/x-handlebars" data-template-name="vegetables">
Select your vegetables:
<ul>
{{#each item in model}}
<li>
{{item.title}} ({{item.season}})
{{input
type="number"
step="1"
placeholder="0"
value=item.quant
}}
</li>
{{/each}}
</ul>
You have {{totalSum}} vegetables.
</script>

<script type="text/x-handlebars" data-template-name="totals">
What you have selected:
<p>{{fruits}} fruits and {{vegetables}} vegetables</p>
</script>



<script src="http://ift.tt/VorFZx"></script>
<script type="text/javascript" src="http://ift.tt/1wkCgu2"></script>
<script type="text/javascript" src="http://ift.tt/1DkRiPT"></script>
<script type="text/javascript" src="http://ift.tt/1wkCi51"></script>






Aucun commentaire:

Enregistrer un commentaire