如何突出显示所选地址?

时间:2015-03-26 11:18:16

标签: ember.js ember-data ember-cli

如果用户点击li条目,则会触发useThisAddress操作,该操作会将isSelected对象中的address设置为true。从那里bind-attr负责设置适当的类(即`border-black')。

这是正确的方法吗?或者有更好的方法吗?

下面的代码有效。但是,我对在isSelected对象上设置trueaddress有点不确定,因为它不是address对象模型中的真实属性。

// Controller
import Ember from 'ember';

export default Ember.Controller.extend({
  active: null,

  actions: {
    useThisAddress: function(address) {
      address.set('isSelected', true);
      var active = this.get('active');
      if (active) {
        active.set('isSelected', false);
      }
      this.set('active', address);
    }
  }
})

// Template
<ul>
  {{#each address in model}}
    <li {{bind-attr class='address.isSelected:border-black'}} {{action 'useThisAddress' address}}>
      Address: {{address.address1}} {{address.address2}}, {{address.city}}, {{address.postalCode}}
    </li>
  {{/each}}
</ul>

4 个答案:

答案 0 :(得分:2)

根据建议here,您只需在控制器中存储一个包含所选项目的单独列表。

答案 1 :(得分:1)

当你说它不是你对象模型的真实属性时,我假设你只是意味着它没有被持久存在。如果是这种情况,并且除了当前显示之外的任何地方没有其他用途,那么长期解决方案是使用组件。请参阅:http://jsbin.com/colacu/1

App = Ember.Application.create();

App.Router.map(function() {
  // put your routes here
});

App.IndexRoute = Ember.Route.extend({
  model: function() {
    return [Ember.Object.create({
      address1: 'add1',
      address2: 'add2',
      city: 'Washington'
    }),
    Ember.Object.create({
      address1: 'add1 again',
      address2: 'add2 again',
      city: 'Seattle'
    })];
  }
});

App.IndexController = Ember.Controller.extend({
  active: null,
  actions: {
    useThisAddress: function(address) {
      address.set('isSelected', true);
      this.set('active', address);
    }
  }
});

App.XAddressComponent = Ember.Component.extend({
  isSelected: false,
  address: null,
  tagName: 'li',
  classNameBindings: ['isSelected'],
  click: function() {
    console.log('clicked!');
    this.sendAction('action', this);
  }
});

模板:

  <script type="text/x-handlebars" data-template-name="index">
    Selected: {{selected.value}}
    <ul>
    {{#each model as |item|}}
      {{x-foo value=item action="select"}}
    {{/each}}
    </ul>
  </script>
  <script type="text/x-handlebars" data-template-name="components/x-foo">
    {{value}}
  </script>

但你所拥有的应该没问题。

答案 2 :(得分:1)

我认为您的直觉反应是正确的 - 您不应该在模型上设置与您的UI严格相关的属性。

组件是Ember中用于存储UI层状态的构建块。在Ember这是一个有点棘手的时间,因为控制器也用于此目的,但他们正在走出困境。很快它将成为所有组件。

当我遇到像你这样的案例(list-with-selected-items)时,我通常会创建一个list组件和一个list-item组件。 list知道选择了哪个项目,并且每个list-item都知道它是否已被选中。对于您的简单情况,其他解决方案之一可能更直接,但我通常会发现这些列表,您最终会想要更多功能(绑定到选定项目,更复杂的模板等)。

因此,一种方法可能如下所示:

{{#address-list selected=selectedAddress as |list|}}
  {{#each address in model}}
    {{#address-list-item item=address list=list}}
      <p>{{address.address1}}</p>
    {{/address-list-item}}
  {{/each}}
{{/address-list}}

您使用块参数(注意:需要Ember 1.10或更高版本)将<address-list>传递到每个<address-list-item>。现在,您的地址列表项可以通过向其发送操作来告诉列表已选择新地址:

App.AddressListItemComponent = Ember.Component.extend({
  classNameBindings: ['active'],

  active: function() {
    return this.get('list.selected') === this.get('item');
  }.property('list.selected', 'item'),

  click: function() {
    this.get('list').send('select', this.get('item'));
  }
});

App.AddressListComponent = Ember.Component.extend({
  actions: {
    select: function(item) {
      this.set('selected', item);
    }
  }
});

这会为您设置所有绑定,将.active类添加到每个<address-list-item>,并允许您从模板外部绑定到<address-list>所选项目

See a working JSBin here

现在,将list定位为使用.send是很尴尬的,这正是为什么我们很快就可以将操作传递给子组件(请查看{{3指导和搜索&#34;改进行动&#34;)。一旦该功能出现,您就可以将select动作处理程序从<address-list>直接传递到每个<address-list-item>。但是现在这是一种方法,当这些变化落地时,它会使重构变得非常简单。

答案 3 :(得分:0)

自己学习Ember,但......我的.02。

列表方法是必须非Emberlike IMO。

假设您希望isSelected是准持久的,那么您的方式应该没问题。只要物体停留,它就会停留 - 甚至可能在路线变化之间(取决于你的型号)。

如果它应该更加短暂。将地址扔到组件中并将isChecked存储在组件控制器中。