Ember ArrayController中的互斥

唐·克里斯蒂(Dom Christie)

我在数组控制器中有一个项目列表。单击某个项目可以使其处于“活动状态”,但是我希望任何时候一次都只有一个项目处于活动状态(类似于单选按钮)。

我通过将活动项存储在计算属性中,然后在阵列控制器上的操作中切换其活动状态来进行此工作,请参阅:http : //emberjs.jsbin.com/wavay/2/edit

但是,这不能解决通过其他某种方式(即通过操作)使某项变为活动状态的情况

我已经尝试过观察isActive变化(使用.observesBefore('@each.isActive')),并翻转的状态activeItem,但是当然,这种方法会导致无限循环。

有没有更好的办法?

唐·克里斯蒂(Dom Christie)

可以使用和的组合来解决Ember.reduceComputed

removedItemaddedItem在回调Ember.reduceComputed给出访问哪些已改变,以及该对象instanceMeta可以被用来存储“有效的”项目,:

App.IndexController = Ember.ArrayController.extend({

  itemController: 'item',

  activeItem: Ember.reduceComputed('@[email protected]', {

    initialValue: null,

    removedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
      if (item.get('isActive')) {
        var previousActiveItem = instanceMeta.activeItem;
        if (previousActiveItem) previousActiveItem.set('isActive', false);
        return instanceMeta.activeItem = item;
      }
      return instanceMeta.activeItem = null;
    },

    addedItem: function (accumulatedValue, item, changeMeta, instanceMeta) {
      return instanceMeta.activeItem;
    }
  })
  …

但是,如果activeItem在任何地方都无法访问它,removedItem并且addedItem永远都不会调用它,那么在手动切换项目之前,这些项目将保持活动状态。要解决此问题,可以将观察者设置为this.get('activeItem')isActive更改属性时进行调用

setActiveItem: function () {
  this.get('activeItem');
}.observes('@each.isActive')

请参阅更新的jsbin:http://emberjs.jsbin.com/wavay/3/edit?js,输出

相关文章:David Hamilton关于阵列计算属性的演讲

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章