Ember 2.0 竭尽全力让一切都成为组件。随着可路由组件的推出,控制器也可能会被淘汰。
Context
然而,在构建用户界面时,我经常遇到一个问题,到目前为止我还没有令人满意的模式:用户界面状态。
我在做什么?
基本上,任何不属于实际数据的状态,都必须逐个对象地进行跟踪。过去,这通常是通过Controllers
,充当模型的代理。这种方法现在已经过时了。新方法是Components
无处不在,只为更好。组件进行簿记、跟踪瞬态状态并返回操作。
不过,我拥有的一个典型模式是共享状态,例如具有可选项目的列表。
问题
构建一个列表组件,具有以下要求:
- 每个项目都可以选择。
- 选择状态会更改 DOM(某些类绑定)。
- 用户可以在列表组件中绘制一个矩形来一次选择多个项目。
- 理想情况下,整个行为可以抽象为 mixin。
问题:选择标志位于哪里?
Attempts
1)一切都是组件。
我将每个项目设为子组件,例如 {{my-list-item}}。该组件跟踪选择状态。问题:列表组件如何更新选择状态?
2) 将状态移出子组件。
将其放在列表组件上。在项目列表旁边的单独状态数组中。优点:该列表具有所需的所有状态。缺点:在列表中添加或删除项目时保持同步是一场噩梦。这意味着子组件无法访问状态。或者也许我可以将它作为绑定值传递给他们?
3)重新引入代理。
想想看,有一种方法可以共享某些状态:将其放在模型上。好吧,不是在实际模型上,以免本地状态污染它们,而是通过设置一个 ArrayProxy 来返回一些ObjectProxy
对于每个项目,保持状态。
优点:这是我能够完全实施的唯一解决方案。缺点:项目的封装和解封装很麻烦。而且,经过几层的传递之后,get
and set
必须经过 4 或 5 个代理,我担心这会影响性能。
此外,它对于 mixins 也效果不佳。我是否应该抽象出一些HasSelection
混合,和一个HasFoldableItems
混合,和一个Sortable
mixin,它们都需要一些状态。
回到绘图板
有没有更好的模式我没有找到?
我发现了以下相关问题,但这使我无处可去:
-
Ember.js - 界面状态应该存储在哪里? https://stackoverflow.com/questions/12425753/ember-js-where-should-interface-state-be-stored(2012 年,建议与我上面的#3 类似的内容)
-
Road to Ember 2.0 - 高级 Ember 应用程序结构反馈? https://stackoverflow.com/questions/30294024/road-to-ember-2-0-high-level-ember-app-structure-feedback(列表中的一些关键问题与此相关)
很好的问题——我实际上去找了一位核心 Ember 团队成员来找出答案,目前的答案是服务。由于组件最好保持无状态(在大多数情况下),因此您可以利用服务来持久保留这种不适合服务器持久模型的状态。
这是 Stef Penner 整理的一个很好的例子,展示了如何在 ember 应用程序中保存“电子邮件草稿”(不是持久化后端)
https://github.com/stefanpenner/ember-state-services 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'));
}
}
});
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)