如何在 Ember.js 中使用 "needs" 控制器的计算 属性?

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

假设我想建立一个有两种不同产品类型 fruitsvegetables 的小商店。每个人在我的店里都有自己的页面,每个人都有独立的路线、控制器和模型。对于这两个产品类别,我想计算 'ordered' 项的总和。

在名为 'totals' 的第三页上,我想显示总和(水果和蔬菜)以及两者的总和。因此,我正在加载产品类型的两个控制器,如下所示: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>

你是真实的接近

控制器需要小写,如:

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

工作here