在Ember 2.0中存储瞬态UI状态的位置

spe*_*ras 7 ember.js

Ember 2.0已经不遗余力地将一切都变成了一个组件.随着可路由的组件即将推出,控制器也可能会逐步淘汰.

上下文

但是,在构建用户界面时我遇到了一个反复出现的问题,到目前为止我还没有令人满意的模式:用户界面状态.

我在做什么?

  • 选择状态
  • 目前的焦点
  • 某些树形显示中的折叠/展开状态

基本上,任何不属于实际数据的状态,但必须逐个对象地跟踪.在过去,过去常常将其Controllers作为模型的代理.这种方法现在已经过时了.新方法Components无处不在,越来越好.组件执行簿记,跟踪瞬态并且您可以恢复操作.

但是,我的典型模式是共享状态,例如带有可选项的列表.

问题

构建列表组件,具有以下要求:

  • 可以选择每个项目.
  • 选择状态更改DOM(某些类绑定).
  • 用户可以在列表组件中绘制一个矩形,一次选择多个项目.
  • 理想情况下,整个行为可以作为mixin抽象出来.

问题:选择标志在哪里?

尝试

1)一切都是一个组成部分.

我将每个项目都设为子组件,比如{{my-list-item}}.该组件跟踪选择状态.问题:列表组件如何更新选择状态?

2)将状态移出子组件.

把它放在列表组件上.在项目列表旁边的单独状态数组中.优点:列表具有所需的所有状态.缺点:在列表中添加或删除项目时保持同步是一场噩梦.这意味着子组件无法访问该状态.或者也许我可以将它作为绑定值传递给它们?

3)重新引入代理.

想到它,有一种方法可以分享一些状态:把它放在模型上.好吧,不是在实际的模型上,以免污染它们与本地状态,但通过设置一个ArrayProxy将返回ObjectProxy每个项目的一些,以保持状态.

优点:这是我设法完全实现的唯一解决方案.缺点:封装和封装物品是一件麻烦事.此外,经过几层传递,get并且set必须通过4 ou 5代理,我担心这将是性能问题.

此外,它不适用于mixins.如果我想抽出一些HasSelectionmixin,HasFoldableItemsmixin和Sortablemixin,他们都需要一些状态.

回到绘图板

是否有一些我没有找到的更好的模式?

我发现了以下相关问题,但这导致我无处可寻:

Tor*_*ups 8

很棒的问题 - 我实际上去了其中一个核心的ember团队成员找出答案,目前的答案是服务.因为组件最好是无状态的(大多数情况下),所以可以利用服务来保持这种不适合服务器持久化模型的状态.

以下是Stef Penner汇总的一个很好的例子,展示了如何在你的余烬应用程序中保存"电子邮件草稿"(这不是持久的后端)

https://github.com/stefanpenner/ember-state-services

示例组件供参考(来自上面的github项目)

export default Ember.Component.extend({
  tagName: 'form',
  editEmailService: Ember.inject.service('email-edit'),
  state: Ember.computed('email', function() {
    return this.editEmailService.stateFor(this.get('email'));
  }).readOnly(),

  actions: {
    save() {
      this.get('state').applyChanges();
      this.sendAction('on-save', this.get('email'));
    },

    cancel() {
      this.get('state').discardChanges();
      this.sendAction('on-cancel', this.get('email'));
    }
  }
});
Run Code Online (Sandbox Code Playgroud)