15

我正在设计一个 API 并使用 Backbone.js 使用它。部分 API 将包括搜索操作。例如,在搜索汽车时,我可能会遇到以下情况:

http://api.mysite.com/search/cars?q=volvo

使用骨干网,我可以看到两个使用结果的选项。

选项 1:搜索是一个集合

var CarSearch = Backbone.Collection.extend({
    model: Car,
    initialize : function(models, options){
        this.query = options.query;
    },
    url: function(){
        return "http://api.mysite.com/search/cars?q="+this.query;
    }
});

var volvos = new CarSearch([], {query:'volvo'});
volvos.fetch();

选项 2:搜索是一个模型,结果是一个集合

var CarSearchResults = Backbone.Collection.extend({
    model: Car
});

var CarSearch = Backbone.Model.extend({
    defaults: {
        "query":"",
        "carSearchResults":null
    },
    url: function(){
        return "http://api.mysite.com/search/cars?q="+this.get('query');
    },
    parse: function(resp,xhr){
        resp.carSearchResults = new CarSearchResults(resp.carSearchResults);
        return resp;
    }
});

var volvoSearch = new CarSearch();
volvoSearch.set({query:'volvo'});
volvoSearch.save();

这些选项的优点/缺点是什么?有没有一种骨干的方式来设计这个?

我倾向于选项 2,因为将诸如分页详细信息或下一个 url 之类的内容添加到响应中似乎更容易。但选项 2 在几个方面似乎更混乱。例如,我会在保存搜索模型时在服务器上生成一个 ID 吗?不要认为我需要通过 ID 获取该模型,删除或更新它也没有任何意义,因为我没有坚持它。

4

3 回答 3

10

我不知道这是否是一个好习惯,但我使用“获取”方法中的“数据”选项进行搜索。

https://stackoverflow.com/a/6659501/1067061

也许它有帮助。祝你好运!

编辑

这是在集合 url 中传递查询参数的正确方法, 对 Docs 的引用显示了如何在 fetch 选项中传递数据属性,数据属性实际上是一个对象,其中键值对引用查询参数及其值

于 2012-06-20T06:02:31.520 回答
5

我会选择选项一。至少imo一个模型应该对应于单个搜索结果,并且集合对应于整个搜索结果集。因此,如果您搜索 volvo 并返回 6 件商品,则每件商品都应该是您收藏中包含的模型。

现在这在很大程度上取决于您如何在服务器上表示结果。例如,如果说您有汽车实例,那么您只需使用查询执行搜索服务器端并将结果对象作为 json 返回。然后,您可以让返回的列表成为符合条件的汽车模型的集合。但是如果您打算以其他方式返回查询结果,那么您将不得不考虑模型应该如何表示数据

于 2012-06-19T18:09:23.117 回答
0

我建议使用一个集合,就像选项 1 一样,但不需要仅为搜索定义一个新集合。

在这里查看我的博客文章:http ://willdemaine.ghost.io/restful-search-with-backbone/

var SearchableCollection = Backbone.Collection.extend({},{

  search: function(query, options){
    var search = $.Deferred();
    options = options || {};
    var collection = new this([], options);
    collection.url = _.result(collection, 'url') + 'search?q=' + query;
    var fetch = collection.fetch();
    fetch.done(_.bind(function(){
      Backbone.Events.trigger('search:done');
      search.resolveWith(this, [collection]);
    }, this));
    fetch.fail(function(){
      Backbone.Events.trigger('search:fail');
      search.reject();
    });
    return search.promise();
  }

});

然后你可以这样做:

var Cars = SearchableCollection.extend({});

var findCars = Cars.search('volvo');  
findCars.done(function(cars){  
  var carsView = new CarsView({
    collection: cars
  });
  carsView.render();
});
于 2014-02-17T21:32:40.740 回答