2015-02-24 1 views
1

Предположим, я хочу построить небольшой магазин с двумя различными типами продуктов fruits и vegetables. Каждый из них имеет собственную страницу в моем магазине, какие отделенные маршруты, контроллеры и модели для каждого. Для обеих категорий продуктов я хочу рассчитать сумму «упорядоченных» предметов.Как использовать вычисленное свойство контроллера «needs» в Ember.js?

На третьей странице, называемой итогом, я хочу отображать обе суммы (фрукты и овощи) и общую сумму обоих. Поэтому я загружаю два контроллера типа продукта следующим образом: needs: ['BasketsFruits', 'BasketsVegetables'].

Вопрос: Почему суммы фруктов и овощей не обновляются на итоговой странице, когда я изменяю количество предметов на других страницах? Является ли мой общий подход правильным?

Пример: Все работает за исключением суммы на странице итогов. 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="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.3.0/handlebars.js"></script> 
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ember.js/1.8.1/ember.js"></script> 
 
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ember-data.js/1.0.0-beta.12/ember-data.js"></script>

+0

Вы получили весь код - почему бы не бросить это в jsbin? Просто говорю ...;) – Kalman

+0

@ KalmanHazins: Я не знаком с jsbin? Что это больше, чем фрагмент кода здесь? – Simon

+0

@ KalmanHazins Сделал это. – Simon

ответ

1

Вы были реальный близко

Контроллеры должны быть строчными, как в:

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

Working here

+0

Хорошо, это было действительно близко. Иногда это действительно помогает создать минимальный пример более сложной проблемы. – Simon

+0

Есть ли способ заставить ember регистрировать сообщение для отладки таких ситуаций? Или вы просто «видели» его? – Simon

+0

Я предполагаю, что я просто «видел это», – Kalman

Смежные вопросы