实施 ember 服务器端搜索

implementing ember server side search

我有一个 "books" 页面,最初显示的是图书列表。我希望用户能够输入搜索文本,然后更改显示的图书列表。根据 embers 数据存储(客户端)中已有的书籍执行此操作很简单,但我想做的是执行搜索服务器端。我该怎么做?

到目前为止,我的 ember 控制器中有以下内容

App.BooksIndexController = Ember.ArrayController.extend({
  search: '',
  actions: {
    query: function() {
      var search = this.get('search');
      var books = this.store.find('books', { search_text: search });
    }
  }
})

但我不知道下一步该做什么。如何通过传入的 books 转换到书籍列表路由?或者是否有更 ember 的方式来做到这一点,比如创建 "search" route/controller/template 并在该页面上显示结果?

我刚刚在我自己的应用程序中实现了它,它可能有点棘手。首先,您需要在您的应用中添加一个输入字段,供用户用于搜索并将其绑定到控制器上的 属性:

{{input value=search classNames='form-control' placeholder="Search books"}}

正如你在上面看到的,它绑定到你的控制器的 search 属性 我已经给它默认的 Bootstrap class form-control

现在,让我们在您的控制器中创建一个名为 books 的新计算 属性:

App.BooksIndexController = Ember.ArrayController.extend({
    ...
    books: function() {
        var model = this.get('model');
        var search = this.get('search');
        var current = 1;
        var books = model.filter(function(item) {
            var reg = '.*'+search.toLowerCase()+'.*';
            var name = item.get('name').toLowerCase();
            if(name.match(reg) && current < 20) { 
                current++;
                return true; 
            }
        });
        return books;
    }.property('search','model.length')
    ...
});

这是做什么的,它会为您建模并检查 name 属性 是否与模型中任何 books 的名称相匹配。您可以根据需要更改它匹配的 属性 或添加新的。我不喜欢一次返回所有匹配项,因此我使用 current 添加了一个限制,以便只返回前 20 个匹配项。如果你愿意,你可以删除它。这样做意味着您将自动显示与商店中已有商品相匹配的商品。

现在,更新您的模板,使其遍历 books 而不是 model 或类似的东西:

{{#each book in books}}
   // do stuff with each book
{{/each}}

你说的真好!现在您在输入时过滤所有书籍,因为 books 属性 将在 search 修改时更新,但现在您需要从 API 中获取新项目.我们使用另一台计算机 属性:

searchApi:function() {
    var search = this.get('search');
    var books = this.store.find('books',{search_text: search});
    var model = this.get('model');
    books.then(function() {           //  In my tests, this isn't
        model.addObjects(books);      //  actually necessary, bit I still
    });                               //  like to keep it for clearness
}.observes('search').on('init')

每当修改搜索字段时,这也会触发对您的 API 的搜索。然后将任何匹配项添加到模型中。这就是为什么我们将 model.length 添加到 books 计算的 属性。任何匹配的项目都将添加到模型中并增加其长度,从而触发书籍再次更新。

这应该是您需要的一切。没有新的路线或控制器,只需在索引中正确执行即可。如果有人对此有更清晰的方法,我很乐意看到它!