更改另一个下拉菜单上的内容的下拉菜单

Drop-down menu which changes the content on an other drop-down menu

我想从 hasMany 关系创建一个下拉菜单,该关系过滤另一个下拉菜单的值。我有 ships 哪个 belongsTo companies 和哪个 haveMany cruises。该网页的用户应该能够 select 什么都没有(table 显示所有船只)或公司(table 只显示该公司的船只)或特定船只( table 只显示一艘船)。如果用户 select 编辑了一个特定的 company,那么只有 company 中的 ships 应该显示在飞船下拉菜单中。 table 舰船也应该更新。

如何创建一组两个下拉菜单(在 table 上方或下方),其行为类似于此示例并过滤 table 的内容?

我知道这个问题是一项艰巨的任务。我试图尽可能地分解它。感谢您的时间和精力。

我的示例应用程序的代码

ember new travel_agency
cd travel_agency
ember install:addon ember-cli-scaffold
ember g scaffold ship name:string
ember g scaffold company name:string
ember g scaffold cruise starts_at:date
ember generate adapter application
ember g http-mock ships
ember g http-mock companies
ember g http-mock cruises
ember install:addon ember-moment

app/adapters/application.js

import DS from 'ember-data';

export default DS.RESTAdapter.extend({
  'namespace': 'api'
});

app/models/company.js

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  ships: DS.hasMany('ship', { async: true })  
});

app/models/ship.js

import DS from 'ember-data';

export default DS.Model.extend({
  name: DS.attr('string'),
  company: DS.belongsTo('company', { async: true }),
  cruises: DS.hasMany('cruise', { async: true })  
});

app/models/cruise.js

import DS from 'ember-data';

export default DS.Model.extend({
  startsAt: DS.attr('date'),
  ship: DS.belongsTo('ship', { async: true })  
});

server/mocks/ships.js

[...]
var shipList = [
  {"id":1,"name":"Carnival Fantasy","company":1,"cruises":[1,2]},
  {"id":2,"name":"Carnival Triumph","company":1,"cruises":[3,4]},
  {"id":3,"name":"Queen Mary 2","company":2,"cruises":[5]},
  {"id":4,"name":"Queen Elizabeth","company":2,"cruises":[6]},
  {"id":5,"name":"Norwegian Jewel","company":3,"cruises":[7,8]}
]
[...]

server/mocks/companies.js

[...]
var companyList = [
  {"id":1,"name":"Carnival"},
  {"id":2,"name":"Cunard"},
  {"id":3,"name":"Norwegian Cruise Line"}
]
[...]

server/mocks/cruises.js

[...]
var cruiseList = [
  {"id":1,"startsAt":"2014-10-01","ship":1},
  {"id":2,"startsAt":"2014-10-15","ship":1},
  {"id":3,"startsAt":"2014-10-30","ship":2},
  {"id":4,"startsAt":"2014-11-10","ship":2},
  {"id":5,"startsAt":"2014-11-20","ship":3},
  {"id":6,"startsAt":"2014-11-20","ship":4},
  {"id":7,"startsAt":"2014-10-20","ship":5},
  {"id":8,"startsAt":"2014-11-20","ship":5}
]
[...]

app/templates/ships/index.hbs

[...]
<tbody>
  {{#each ship in model}}
    <tr>
      <td>
        {{ship.name}}
      </td>
      <td>
        {{ship.company.name}}
      </td>
      <td>
        {{#each cruise in ship.cruises}}
          {{moment date "L" cruise.startsAt}}, 
        {{/each}}
      </td>
      <td>
        {{link-to "Edit" "ships.edit" ship}}
      </td>
      <td>
        {{link-to "Show" "ships.show" ship}}
      </td>
      <td>
        <a href="#" {{action "remove" ship}}>Remove</a>
      </td>
    </tr>
  {{/each}}
</tbody>
[...]

我不会深入研究您的整个应用程序。因为它与您想要的功能没有太大关系。如果我理解正确的话,您想根据第一个选项列表的值过滤第二个选项列表。

您需要一个包含两个选项列表的模板

{{view "select" content=model.colors value=selectedItem}}
color: {{selectedItem}}
{{view "select" content=filteredBoats optionLabelPath="content.boat"}}

您需要一条提供模型的路线:

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return { 
      colors: [],
      boats: []
    };
  }
});

然后你需要一个控制器连接起来:

App.IndexController = Ember.Controller.extend({
  filteredBoats: function(){
      var selI = this.get('selectedItem');

      return this.get('model.boats').filter(
        function(boat) { 
           return boat.color == selI; 
        });
  }.property('selectedItem')
});

让我们回顾一下,看看会发生什么。

  1. 在视图中,我们将第一个选项列表的结果绑定到控制器中的selectedItem
  2. 在控制器中,我们创建一个计算 属性 并根据它的值
  3. 过滤 model.boats
  4. 在视图中,我们将第二个选项列表绑定到计算的 属性。

看到这个jsbin