Ember.js - 接口状态应该存储在哪里? [英] Ember.js - where should interface state be stored?

查看:12
本文介绍了Ember.js - 接口状态应该存储在哪里?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于接口状态(而不是持久模型状态)应该存在于 Ember.js 应用程序中的位置是否有官方故事?

Is there an official story for where interface state (as opposed to persisted model state) should live in an Ember.js app?

Router 文档的响应用户发起的事件"部分,有一个将点击事件委托给照片的showPhoto"方法的例子,但让模型展示"本身似乎是一种令人不快的混合问题.

In the "Responding to User-initiated Events" part of the Router docs, there's an example of delegating click events to a photo's "showPhoto" method, but having a model "show" itself seems like an undesirable mixing of concerns.

我知道在许多情况下状态应该存储在路由器中,以便接口状态在 URL 中表示,并且如果您刷新页面或将 url 发送给某人,则会恢复.但是非层次状态呢,例如页面上选择的项目列表?

I understand that in many cases state should be stored in the router so that the interface state is represented in the URL and is restored if you refresh the page or send the url to someone. But what about non-hierarchical state, such as the list of items selected on a page?

理想情况下,该类型的状态将被序列化为查询/哈希参数(例如:http://www.hipmunk.com/flights/QSF-to-NYC#!dates=Sep15,Sep16p1;kind=flight&locations=QSF,YYZ&dates=Sep15,Sep23~tab=1 )但据我所知,路由器不提供该功能,是吗?

Ideally that type of state would be serialized as query/hash params (eg: http://www.hipmunk.com/flights/QSF-to-NYC#!dates=Sep15,Sep16p1;kind=flight&locations=QSF,YYZ&dates=Sep15,Sep23~tab=1 ) but as far as I know, the router doesn't offer that functionality, does it?

在 BackboneConf 上,Jeremy Ashkenas 说在 Backbone 中正确的方法是将状态也存储在模型上(他有一个带有选择"字段的模型示例).但我相信 Tom Dale 说他认为这不是一个好主意,而不是应该如何在 Ember 中完成.不幸的是,我不记得他提到过应该如何去做.

At BackboneConf, Jeremy Ashkenas said that the right way to do that in Backbone was to just store the state on the model too (he had an example of a model with a "selected" field). But I believe Tom Dale said he didn't think that was a good idea, and not how it should be done in Ember. Unfortunately I don't remember him mentioning how it should be done.

推荐答案

如果您希望状态可路由(即通过 url 可达),那么它需要通过 ember 的路由器进行序列化和反序列化.如果状态是瞬态且不可路由的,那么最好将其保存在控制器上.

If you want state to be routable (i.e. reachable via a url), then it needs to be serializable and deserializable via ember's router. If state is transient and not routable, then it is probably best kept on the controller.

如果您需要跨多个模型表示复杂的接口状态(例如,用于选择列表中的项目),请考虑维护一个包含底层数据模型的特定于控制器的对象数组.我认为直接在模型上表示视图状态是一种黑客行为,尤其是当这些模型跨多个视图使用时.

If you need to represent complex interface state across multiple models (say, for selecting items in a list), consider maintaining a controller-specific array of objects that wrap underlying data models. I think it's hackish to represent view state directly on models, especially if those models are used across multiple views.

对于您提供的示例,您可以执行以下操作来连接复杂的路由:

For the example you provided, you might do something like this to hook up a complex route:

Ember.Route.extend({
  route: "flights/:cities/dates/:dates",

  serialize: function(router, context){
    return {cities: context.get('cities'),
            dates:  context.get('dates')};
  },

  deserialize: function(router, params){
    // return a context object that will be passed into connectOutlets()
    return {cities: params.cities,
            dates:  params.dates};
  },

  connectOutlets: function(router, context) {
    // pass the context from deserialize() in as the content of a FlightController
    router.get('applicationController').connectOutlet('flight', context);
  }
})

请注意,您也可以使用诸如flights?cities=:cities&dates=:dates"之类的路线,但上述路线可能更简洁,对 SEO 更友好.

Note that you could also use a route such as "flights?cities=:cities&dates=:dates" but the above is probably cleaner and more SEO-friendly.

在 Gabriel 的评论之后进行了扩展:如果您想维护一组搜索,每个搜索都驻留在自己的选项卡中,我建议将这些搜索的数据保留在应用程序级别数组(例如 App.currentUser.activeSearches).我的理由是您不希望每次用户切换选项卡时都必须重新创建这些数据.相反,路由器将在 deserialize() 中检索此数据,然后将其作为上下文传递给 connectOutlets().切换选项卡时,应根据此对象快速重新构建表示此数据的视图和控制器.让我从上面扩展我的例子:

Expanded upon after Gabriel's comments: If you want to maintain an array of searches, each of which resides in its own tab, I'd recommend keeping the data for those searches in an application-level array (e.g. App.currentUser.activeSearches). My reasoning is that you don't want to have to recreate this data every time a user switches tabs. Instead, the router would retrieve this data in deserialize() and then pass it as the context to connectOutlets(). The view and controller to represent this data should be quickly re-constructed based upon this object when switching tabs. Let me extend my example from above:

Ember.Route.extend({
  route: "flights/:cities/dates/:dates",

  serialize: function(router, context){
    return {cities: context.get('cities'),
            dates:  context.get('dates')};
  },

  deserialize: function(router, params){
    // find or create a "Search" object that contains the filters and results,
    // which will be passed into connectOutlets()
    return App.currentUser.findOrCreateSearch({cities: params.cities,
                                               dates:  params.dates});
  },

  connectOutlets: function(router, context) {
    // pass the context (a search object) from deserialize() in as the content of a FlightController
    router.get('applicationController').connectOutlet('flight', context);
  }
})

这篇关于Ember.js - 接口状态应该存储在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆