观察Ember.ArrayController中的任何Ember.ObjectController何时更改

时间:2015-04-14 19:42:02

标签: javascript ember.js ember-cli

我试图在Ember应用程序中设置批量操作复选框(用于删除所选项目)。如果选中任何一个复选框,则可以显示或隐藏批量操作下拉菜单。我还没有进入下拉列表,因为我无法弄清楚如何观察阵列中的所有元素。我怎么能:

  1. 设置阵列控制器,以便观察所有客户端对象
  2. 获取更改后的已检查项目数
  3. 另外:我是否正在接近我如何接近客户端itemController的惯例?
  4. 应用/模板/ clients.hbs

    <section id="clients">
        <h4>my clients</h4>
        <ul>
        {{#each itemController="clients/client"}}
            <li>
                {{input type="checkbox" name="markedForDeletion" checked=markedForDeletion}}
                {{#link-to 'clients.show' this}}
                    {{clientName}}
                {{/link-to}}
            </li>
        {{/each}}
    
        </ul>
    </section>
    {{#link-to 'clients.new'}}Add client{{/link-to}}
    {{outlet}}
    

    router.js

    import Ember from 'ember';
    import config from './config/environment';
    
    var Router = Ember.Router.extend({
      location: config.locationType
    });
    
    export default Router.map(function() {
      this.resource('clients', function() {
        this.route('show', {path: '/:client_id'});
        this.route('new');
      });
    });
    

    应用/路由/ clients.js

    import Ember from 'ember';
    export default Ember.Route.extend({
        model: function() {
            return this.store.find('client');
        }
    });
    

    应用/模型/ client.js

    import DS from 'ember-data';
    export default DS.Model.extend({
      clientName: DS.attr('string'),
      clientEmail: DS.attr('string')
    });
    

    应用/控制器/ clients.js

    import Ember from 'ember';
    export default Ember.ArrayController.extend({
        checkBoxesChanged: function() {
        // This fires only once, when the /clients/ route is activated
        console.log('markedForDeletion in array changed');
      }.observes('@each.clients')
    });
    

    应用/控制器/客户端/ client.js

    import Ember from 'ember';
    export default Ember.ObjectController.extend({
        markedForDeletion: true,
        markedForDeletionChanged: function(){
            // This fires correctly
            console.log('markedForDeletion object changed');
        }.observes('markedForDeletion')
    });
    

    编辑:类似问题here,但我担心这些答案对我没那么大帮助。

2 个答案:

答案 0 :(得分:1)

这有几个解决方案。由于您的解决方案只需要额外的检查属性,我认为ObjectProxy将满足您的需求。但是,如果您需要更多功能,那么组件将更适合。

注意:在我们深入研究解决方案之前,重要的是要注意ArrayController,ObjectController和ItemController都已被弃用。

由于我们不能使用itemController,您可以删除 app / controllers / clients / client.js

应用/模板/ clients.hbs

<section id="clients">
    <h4>my clients</h4>
    <ul>
    {{#each clientsWithMarker as |client|}}
        <li>
            {{input type="checkbox" name="markedForDeletion" checked=client.markedForDeletion}}
            {{#link-to 'clients.show' client}}
                {{client.clientName}}
            {{/link-to}}
        </li>
    {{/each}}

    </ul>
</section>
{{#link-to 'clients.new'}}Add client{{/link-to}}
{{outlet}}

应用/控制器/ clients.js

import Ember from 'ember';
export default Ember.Controller.extend({
    clientsWithMarker: Ember.computed.map('model', function(client) {
        return Ember.ObjectProxy.create({
            content: client,
            checked: false
        });
    }),

    // This computed property returns an array of ObjectProxies that
    // are checked. It is recalculated automatically
    checkedClients: Ember.computed.filterBy('clientsWithMarker', 'checked', true),

    checkBoxesChanged: function() {
    // This fires only once, when the /clients/ route is activated
    console.log('markedForDeletion in array changed');
  }.observes('clientsWithMarker.@each.checked')
});

这个应该有效,但我还没有真正测试过这个特定的代码。

答案 1 :(得分:1)

以下是ember中多选复选框功能实现的工作示例。

http://alexdiliberto.com/posts/ember-toggle-all-checkbox/

http://emberjs.jsbin.com/coliwiwa/5/edit?html,css,js,output

基本上,当循环遍历数组中的每个项时,itemController将自身的引用发送到parentController,而parentController在数组中维护这些引用。这里isChecked属性在每个itemController中定义,而不是附加到数组成员。 我们在生产代码中使用这种方法。

替代方法可以是在新数组的每个数组项上使用ObjectProxy并附加isChecked属性,并观察它。

例如。如果colors是数组,那么

var newColors = colors.map(function(color){
 return Ember.ObjectProxy.create({
   isChecked: false, 
   content: color
   } 
)};

通过这种方式,我们创建了具有isChecked属性的newColors数组,我们可以将其循环播放,但我们还没有触及各个项目。