Вопрос по backbone.js, search, query-string – Получить коллекцию Backbone с параметрами поиска

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   ответа
85

Получить Backbone.js с параметрами отвечает на большинство ваших вопросов, но я поставил некоторые и здесь.

Добавитьdata параметр вашегоfetch вызов, пример:

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

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

Теперь в ваш URL-адрес вызова добавлены параметры, которые вы можете анализировать на стороне сервера.

Это должен быть принятый ответ.
Я понятия не имел о $ .param ИЛИ о передаче {data: ...} в вызов извлечения. Спасибо тебе за это!
Извините, что это заняло так много времени! sa125
Согласен. Поиск обычно выполняется с помощью GET, а не POST. Я вижу достоинства Поисковой модели.save() особенно подходите, если вы используете сервер для регистрации / сохранения результатов поиска, но этот ответ является более стандартным (и большинство людей используют JavaScript на стороне клиента для отслеживания запросов в любом случае).
5

что текущая версия Backbone (или, может быть, jQuery) автоматически переводит строкуdata значение, поэтому нет необходимости звонить$.param больше.

Следующие строки дают одинаковый результат:

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

Строка запроса будетfilter=abc&page=1.

РЕДАКТИРОВАТЬ: Это должен был быть комментарий, а не ответ.

Полезно, тем не менее!
13

Я думаю, что вы должны разделить функциональность:

The Search Model

Это правильноеresource на вашей стороне сервера. Единственное допустимое действиеCREATE.

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

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

Он отвечает за сбор списка моделей Result.

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

Вы видите, что это представление делает интеллектуальную работу, слушая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
  }
});

Я думаю, что такое решение очень чистое, элегантное, интуитивно понятное и расширяемое.

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, чем я.

Этот подход я использовал до тех пор, пока не увидел ответ @ jakee выше.
Я бы сказал, что это была ошибка Бэкбона, что не проще сделать это другим способом.
Здесь есть небольшая связь с этой ссылкой DOM в Коллекцию. Но я сделал более ужасные вещи :)
^ - & GT; плюс принятый ответ делает то же самое и полагается на jQuery .val () вместо базовых моделей.

Похожие вопросы