Backbone.js - filtering a collection with a value from input

I'm looking for a way to filter my base collection with a value from an input field - for this I defined an event listener with a view ("keyup input.searchBookmark": "search"):

window.BookmarksListView = Backbone.View.extend({ events: { "keyup input.searchBookmark": "search" }, el: $('#bookmarksList'), initialize: function() { this.model.bind("reset", this.render, this); this.model.bind("add", function(bookmark) { $('#bookmarksList').append(new BookmarksListItemView({model: bookmark}).render().el) }); }, render: function(eventName) { _.each(this.model.models, function(Bookmarks) { $(this.el).append(new BookmarksListItemView({model: Bookmarks}).render().el); }, this); return this; }, renderList: function(bookmarks) { alert(bookmarks); }, search: function(event) { alert(event); var query = $("#searchBookmark").val(); this.renderList(this.model.search(query)); } }); 

HTML:

 <form class="pull-left" action=""> <input placeholder="Bookmarks..." type="text" class="searchBookmark" id="searchBookmark" value=""> </form> 

The input element is not part of the bookmarksList element.

My problem is that nothing happens if I enter some text in the input - what could be the problem?

+1
source share
2 answers

When you use the events object in the Backbone view, they are linked using the jQuery delegate :

delegateEvents delegateEvents([events])

Uses the jQuery delegate function to provide declarative callbacks for DOM events in a view. If the events hash is not passed directly, this.events used as the source.

Thus, only those elements that are in the this.el will be linked using the events view. You say that

The input element is not part of the bookmarksList element

therefore, nothing is bound to input.searchBookmark , and your search method will never be called.

You have several options:

  • Move the search box to #bookmarksList so that the list is offline.
  • Move search event processing to a view containing a search box. Then set up a separate set of bookmarks for #bookmarksList to display and update the display when the collection changes. Then, the view in the search box can filter the main collection of bookmarks, update the collection that #bookmarksList uses, and let Backbone handle events from there.
  • Manually bind to input.searchBookmark when your view #bookmarksList displayed and untied in the remove method.

The first two are pretty standard Backbone settings, so don't talk about them anymore; the third is a little strange and will look something like this:

 window.BookmarksListView = Backbone.View.extend({ events: { }, initialize: function() { _.bindAll(this, 'search'); //... }, render: function(eventName) { $('input.searchBookmark').on('keyup', this.search); //... }, remove: function() { $('input.searchBookmark').off('keyup', this.search); // Other cleanup... }, //... }); 

I do not recommend this approach, but your views should hold them in your hands.

+3
source

I handle filtering, having a view for the input field that causes the message:

 class App.Views.SidebarListSearchView extends Backbone.View el: "input#list-search" events: keyup: "filter" # Send a message with the value we are searching for. filter: => App.Mediator.trigger("filterLists", $(@el).attr("value")) 

... that other kinds of bugs:

 class App.Views.SidebarFolderView extends Backbone.View ... initialize: -> # Re-render the shebang with a filter applied. App.Mediator.bind("filterLists", @filterLists) ... 
0
source

Source: https://habr.com/ru/post/908577/


All Articles