ember-data:很难将数据存入商店

时间:2017-02-03 15:49:47

标签: ember.js ember-data

我有一个现有的搜索应用程序,我在服务器端构建,使用由python / flask处理的elasticsearch。在客户端,它使用JS / jQuery和把手来解析和呈现数据。

我想更进一步,并在ember中构建它,因为“控件”(过滤器,排序,分页等)使其成为SPA的完美候选者。

我理解余烬基础知识,但我觉得我已经碰到了一个带有余烬数据的墙 - 即如何将我的数据存入商店以便我可以绑定动作。有人能指出我正确的方向吗?

我现有的JSON API可以这样访问:

http://localhost:8000/search?q=shirt&paging=18&filter-price=100

并返回JSON,如下所示:

{
  "aggregations": {
    "breadcrumb": [], 
    "color": [], 
    "price": [], 
    "size_apparel": [],
    "size_jewelry": []
  }, 
  "meta": {
    "agg_list": [], 
    "default_sort": "", 
    "key_translations": {}, 
    "paging": 18, 
    "paging_options": [], 
    "sort_methods": [],
    "from": 0, 
    "hits": 89, 
    "pages": 5, 
    "q": "shirt"    
  }, 
  "results": [
    {
      "creation_date": "", 
      "image": "", 
      "images": {
        "altimg1": "", 
        "large": "", 
        "regular": "/", 
        "small": ""
      }, 
      "name": "This Product", 
      "price": "19.95", 
      "skuid": "ABC123", 
      "url": "shirt.html"
    }, 
    {...}, 
    {...}
  ] 
}

这是可用的还是我需要重写后端?我已经修改了访问数据并且有一些非常粗糙的工作。我实际上可以看到'结果'数据,但我没有IDEA如何访问'meta'和'aggregations'数据。我认为这是“sam有效载荷中的多个模型”而RSVP.hash应该可以工作......但是ember-data似乎要求每个模型都有一个id。这对于“结果”模型是有意义的,但不适用于聚合,绝对不适用于元。

现在我只想让它出现。

对于初学者,我的适配器是:

export default DS.RESTAdapter.extend({
    host: 'http://localhost:8000',
    pathForType() {
        return 'search';
    }
});

测试控制器是:

export default Ember.Controller.extend({
  queryParams: ['q','paging'],
  q: 'shirt',
  paging: '18'
});

我的'结果'模型是:

const { attr } = DS;

export default Model.extend({
    'creation_date': attr('string'), 
    'has_pricerange': attr('string'), 
    'image': attr('string'), 
    'name': attr('string'), 
    'price': attr('string'), 
    'skuid': attr('string'), 
    'url': attr('string')
});

路线:

export default Ember.Route.extend({
  model(params) {
    return this.store.query('result', { 
        q: params.q,
        paging: params.paging
    });   
  }
});

串行器:

export default DS.RESTSerializer.extend({
    primaryKey: 'skuid'
});

这对jquery来说很容易 - 只需$ .get然后用对象表示法访问数据。我知道ember不是jquery,但似乎应该更容易访问数据。我错过了什么吗?采取错误的方法?我应该从头开始吗?

2 个答案:

答案 0 :(得分:3)

Ember Data是Ember拼图的一大部分,但绝不是必需的。您是否应该使用Ember Data实际上取决于数据的性质,API的控制以及您期望的未来可靠性

您数据的性质

Ember Data真正擅长典型的模型/实体类型数据。具有属性的“事物”,可以相互关联。如果您的数据遵循该模式,那么Ember Data可能非常合适。

控制您的API

正如其他答案中所提到的,如果您可以购买JSON API格式,那么您可以免费获得很多。这已成为Ember Data的标准,但并非Ember独有。很多服务器端选项都可以使用many existing frameworks轻松地序列化这些资源。如果您无法更改来自服务器的数据,或者更容易在前端处理它,您可以在Ember中自定义适配器/序列化器的路径。

期望的未来可靠性

Ember Data允许您更换适配器/序列化器,同时保持模型的正常运行。如果您希望将来应用程序处理不同的源,可能需要从使用自己的API转换为使用本地存储或者像firebase这样的第三方服务,这是可取的。如果不计划进行大量更改,您可以执行基本的ajax调用并在model挂钩中返回一个承诺,而Ember将或多或少地起作用。我建议使用针对ember-network API指定的fetch,并且可能会越来越多地支持FastBoot兼容请求。

需要考虑的其他事项是,Ember Data和使用Ember对象可能很重,具体取决于您传入的每个模型的实例数量。

其他人也正在解决这个问题。 Toran Billups用ember-redux推动了redux模式,这是另一种思考如何处理数据的好方法。

您的用例

所以你可以:

使用带有find

的Ember数据

看一下数据的形状,看起来您提供的搜索服务比查询特定模型/实体更多。 Ember Data确实有find方法,但是您提供的元数据量可能会因模型用例而过载。

忘记Ember数据并使用搜索结束点

model: function(params),使用模型钩子中的参数构造搜索结束点的url,并返回一个promise(根据需要添加then来塑造数据)

查询搜索结束点(API重构)

与上述类似的想法,但您可以使用获取产品ID并使用它们来查询产品的ember数据存储。

类似于:

fetch("service-end-point?with=queryparams")
  .then(result => {
    return {
      products: this.store.findMany(Product, result.ids);
    };
  });

我认为最简单的方法是直接在控制器中处理和整形数据,并跳过Ember Data。如果您需要特定的计算属性绑定,则没有理由可以使用您想要的形状扩展Ember.Object,然后使用.map之类的内容从网络请求中获取结果并将其应用为payload => Object.create(payload)

如果您对这些想法有任何疑问,请与我们联系。

答案 1 :(得分:1)

我建议您阅读指南的this section,特别是有关$.getJSON的内容。 Ember旨在使用强大的商店。如果您使用的是标准API(例如JSON API),则更容易使用;你可以直接使用Ember数据代码。但如果没有,你将不得不编写一些序列化代码,以便Ember知道如何使用你的api。一旦完成,您的组件代码将不会耦合到您的数据提取代码。

如果您仍在进行原型设计,则可以使用$ .getJSON。