如何实现搜索功能?

How to implement a search feature?

我有一个搜索功能,允许用户按产品筛选。通常,我会有以下内容:

// Routes
import Ember from 'ember';

export default Ember.Route.extend({
  model: function(params) {
    return Ember.RSVP.hash({
      keyword: params.keyword,
      products: this.store.find('product', { name: params.keyword, status: 'available' })
    });
  },

  setupController: function(controller, model) {
    controller.set('content', model);
  }
});

在模板中:

// Template
{{#if products.length}}
  <ul>
    {{#each products}}
      <li>
        Name: {{name}}
      </li>
    {{/each}}
  </ul>
{{else}}
  <p>No products</p>
{{/if}}

哪个有效。但是,如果我想要一个搜索 API 端点来处理产品过滤...

路由中的模型挂钩是什么样子的?我应该创建一个 Ember 搜索模型吗?这是正确的做法吗?

如果不是,我应该改用 Ember.$.ajax 吗?其他方法?

我不认为你会做任何不同的事情。当您使用查询参数执行 store.find 时,在您的情况下 { name: params.keyword, status: 'available' },查询的结果 return 将显示在控制器中;假设您使用的是 ArrayController。您的模型和控制器不需要更改,您只需根据查询的结构来控制您想要的内容。

// display all models that are in the store    
store.find('someModel')  

// display a single model   
store.find('someModel', 123) // will display a single model

// display only models that match the query
store.find('someModel', { name: params.keyword, status: 'available' }

现在,如果您要处理不符合规范的端点,即。您的搜索端点不只是在 /products?name=some-name&status=available,那么您可能需要稍微修改您的适配器以处理这些差异。在适配器中执行此操作意味着您仍然有一个简单的 controller/route/model,并且隐藏了适配器中特定于端点的复杂性。

Ember.js 提供在资源级别处理 _query_ing 数据的工具。这是一个建议的解决方案,后面还有一些更接近您期望的其他选项。

预期用例

  1. 在 Ember 中,您不必将 "representation" 数据映射到服务器端点。您不必 RESTful 使用 Ember 路线(如 URLs)。
  2. 在Ember中,一个"representation"数据(比如一个Controller和View集)可以参考多个数据源。
  3. 使用 "q" 参数对您的资源进行全文搜索。
  4. 所有这一切背后的目的是降低后端的复杂性 API。如果您为 一个 资源构建搜索和查询系统,则可以将其重新用于后端的所有其他资源。

创建搜索 URL

// in your router
this.route('search')

创建搜索路径以获取所需数据

Ember.RSVP.hash({
  stores: this.store.find('store', {
    rate_minimum: 4.0,
    near: 'lat:long',
    q: 'local store name'
  }),

  products: this.store.find('product', {
    price_maximum: '',
    near: 'lat:long',
    q: 'famous shoe brand'
  })
});

快速响应方式

使用Store#pushPayload

使用 Ember.$.ajax 从您的搜索端点下载数据。请记住,只要您的数据有名称,您就可以使用 Store#pushPayload 将多个不相关的数据类型加载到 Ember 数据的存储中。

在您的路线的 model 挂钩中,使用 this.store.all('product') 到 return 内存中的所有产品,而无需发送请求。在将来的某个时候 Ember 将更新这个数组。您可以使用 Ember.RSVP 到 "represent" 多个资源。

在您的 Controller 中,除了向 API 发出新请求以获取更多相关数据之外,还可以使用 filterBy 等数组操作为用户的查询提供实时更新。

这会导致立即响应,同时等待后端回复并立即使用后端响应更新 "representation" 数据。

Ember 无数据方式

  1. 创建搜索路线
  2. 使用Ember.$.ajax获取数据
  3. 将其作为路线的 model 钩子
  4. 传递
  5. 每当用户更改搜索条件时发送另一个 ajax 请求