【问题标题】:Fetch Backbone collection with search parameters使用搜索参数获取 Backbone 集合
【发布时间】:2012-09-07 10:06:14
【问题描述】:

我想使用Backbone.js 实现一个搜索页面。搜索参数取自简单形式,服务器知道解析查询参数并返回结果的 json 数组。我的模型或多或少是这样的:

App.Models.SearchResult = Backbone.Model.extend({
    urlRoot: '/search'
});

App.Collections.SearchResults = Backbone.Collection.extend({
    model: App.Models.SearchResult
});

var results = new App.Collections.SearchResults();

我希望每次执行results.fetch() 时,搜索表单的内容也将与GET 请求一起序列化。有没有一种简单的方法来添加它,或者我做错了,可能应该手动编码请求并根据返回的结果创建集合:

$.getJSON('/search', { /* search params */ }, function(resp){
    // resp is a list of JSON data [ { id: .., name: .. }, { id: .., name: .. }, .... ]
    var results = new App.Collections.SearchResults(resp);

   // update views, etc.
});

想法?

【问题讨论】:

    标签: search backbone.js query-string


    【解决方案1】:

    Backbone.js fetch with parameters 回答了您的大部分问题,但我也将一些问题放在这里。

    data 参数添加到您的fetch 调用中,例如:

    var search_params = {
      'key1': 'value1',
      'key2': 'value2',
      'key3': 'value3',
      ...
      'keyN': 'valueN',
    };
    
    App.Collections.SearchResults.fetch({data: $.param(search_params)});
    

    现在您的呼叫 url 添加了可以在服务器端解析的参数。

    【讨论】:

    • 我同意。搜索通常使用 GET 而不是 POST 完成。我看到了搜索模型.save() 方法的优点,特别是如果您使用服务器来记录/存储搜索,但这个答案更标准(而且大多数人都在使用客户端 javascript 来跟踪搜索)。跨度>
    • 我不知道 $.param 或者将 {data: ...} 传递给 fetch 调用。谢谢你!
    【解决方案2】:

    注意:代码已简化且未经测试

    我认为你应该拆分功能:

    搜索模型

    它是您服务器端的正确资源。唯一允许的操作是CREATE

    var Search = Backbone.Model.extend({
      url: "/search",
    
      initialize: function(){
        this.results = new Results( this.get( "results" ) );
        this.trigger( "search:ready", this );
      }
    });
    

    结果集合

    它只是负责收集Result模型列表

    var Results = Backbone.Collection.extend({
      model: Result
    });
    

    搜索表单

    你看到这个视图正在做智能工作,监听form.submit,创建一个新的Search对象并将它发送到服务器成为created。这个created 任务并不意味着搜索必须存储在数据库中,这是正常的creation 行为,但并不总是需要这样。在我们的例子中,create 搜索意味着搜索数据库以寻找具体的寄存器。

    var SearchView = Backbone.View.extend({
      events: {
        "submit form" : "createSearch"
      },
    
      createSearch: function(){
        // You can use things like this
        // http://stackoverflow.com/questions/1184624/convert-form-data-to-js-object-with-jquery
        // to authomat this process
        var search = new Search({
          field_1: this.$el.find( "input.field_1" ).val(),
          field_2: this.$el.find( "input.field_2" ).val(),
        });
    
        // You can listen to the "search:ready" event
        search.on( "search:ready", this.renderResults, this )
    
        // this is when a POST request is sent to the server
        // to the URL `/search` with all the search information packaged
        search.save(); 
      },
    
      renderResults: function( search ){
        // use search.results to render the results on your own way
      }
    });
    

    我认为这种解决方案非常简洁、优雅、直观且非常可扩展。

    【讨论】:

      【解决方案3】:

      找到了一个非常简单的解决方案——覆盖集合中的url()函数:

      App.Collections.SearchResults = Backbone.Collection.extend({
      
        urlRoot: '/search',
      
        url: function() {
          // send the url along with the serialized query params
          return this.urlRoot + "?" + $("#search-form").formSerialize();
        }
      });
      

      希望这不会让任何比我拥有更多 Backbone / Javascript 技能的人感到恐惧。

      【讨论】:

      • 这里与集合中的 DOM 引用有一点耦合。但我做了更丑陋的事情:)
      • 我会说这是 Backbone 的错,以另一种方式做到这一点并不容易。
      • ^--> 加上接受的答案也是如此,并且依赖于 jQuery .val() 而不是骨干的模型。
      • 这是我在看到上面@jakee 的回答之前一直使用的方法。
      【解决方案4】:

      似乎当前版本的 Backbone(或者可能是 jQuery)自动将 data 值字符串化,因此无需再调用 $.param

      以下行产生相同的结果:

      collection.fetch({data: {filter:'abc', page:1}});
      collection.fetch({data: $.param({filter:'abc', page:1})});
      

      查询字符串将为filter=abc&page=1

      编辑:这应该是评论,而不是回答。

      【讨论】:

      • 有帮助,不过!
      猜你喜欢
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      • 2013-07-29
      • 1970-01-01
      • 1970-01-01
      • 2011-11-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多