Коллекция Fetch Backbone с параметрами поиска
Я хотел бы реализовать страницу поиска с помощью 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.
});
Мысли?
Ответы
Ответ 1
Backbone.js fetch с параметрами отвечает на большинство ваших вопросов, но я также добавил некоторые из них.
Добавьте параметр data
к вызову fetch
, например:
var search_params = {
'key1': 'value1',
'key2': 'value2',
'key3': 'value3',
...
'keyN': 'valueN',
};
App.Collections.SearchResults.fetch({data: $.param(search_params)});
Теперь ваш URL-адрес вызова добавил параметры, которые вы можете проанализировать на стороне сервера.
Ответ 2
Внимание: код упрощен и не протестирован
Я думаю, вы должны разделить функциональность:
Модель поиска
Это правильный ресурс на вашей стороне сервера. Разрешено только действие 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
Поиск означает поиск в БД, который ищет конкретные регистры.
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();
}
});
Надеюсь, это не ужасает любого, у кого есть немного больше навыков магистральной /Javascript, чем я.
Ответ 4
Кажется, что текущая версия Backbone (или, может быть, jQuery) автоматически строит значение data
, поэтому нет необходимости называть $.param
больше.
Следующие строки дают одинаковый результат:
collection.fetch({data: {filter:'abc', page:1}});
collection.fetch({data: $.param({filter:'abc', page:1})});
Запрос будет filter=abc&page=1
.
EDIT: Это должен был комментарий, а не ответ.