21

を使用して検索ページを実装したいのですが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.
});

考え?

4

4 に答える 4

84

パラメータを使用したBackbone.jsフェッチはほとんどの質問に答えますが、ここにもいくつか入れます。

data呼び出しにパラメータを追加しますfetch。例:

var search_params = {
  'key1': 'value1',
  'key2': 'value2',
  'key3': 'value3',
  ...
  'keyN': 'valueN',
};

App.Collections.SearchResults.fetch({data: $.param(search_params)});

これで、呼び出しURLに、サーバー側で解析できるパラメーターが追加されました。

于 2012-09-07T10:52:12.310 に答える
13

重要:コードは単純化されており、テストされていません

機能を分割する必要があると思います。

検索モデル

これは、サーバー側の適切なリソースです。許可される唯一のアクションはですCREATE

var Search = Backbone.Model.extend({
  url: "/search",

  initialize: function(){
    this.results = new Results( this.get( "results" ) );
    this.trigger( "search:ready", this );
  }
});

結果コレクション

結果モデルのリストの収集を担当しているだけです

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

検索フォーム

このビューがインテリジェントなジョブを作成し、リッスンしform.submit、新しいSearchオブジェクトを作成し、それをサーバーに送信していることがわかりますcreated。このcreatedミッションは、検索をデータベースに保存する必要があることを意味するものではありません。これは通常のcreation動作ですが、必ずしもこのようにする必要はありません。この場合create、検索とは、具体的なレジスタを探してDBを検索することを意味します。

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
  }
});

この種のソリューションは、非常にクリーンで、エレガントで、直感的で、非常に拡張性があると思います。

于 2012-09-07T10:41:06.657 に答える
6

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スキルを持っている人を怖がらせないでしょう。

于 2012-09-07T10:33:40.733 に答える
6

現在のバージョンのBackbone(またはjQuery)はdata値を自動的に文字列化するように思われるため、これ以上呼び出す必要はあり$.paramません。

次の行でも同じ結果が得られます。

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

クエリ文字列はになりますfilter=abc&page=1

編集:これは答えではなくコメントであるべきでした。

于 2015-10-06T00:21:22.717 に答える