Turn jQuery code into Backbone.js structure

I am pretty useful for Backbone.js, but I like jQuery. However, I like the way Backbone organizes code in models, views, and collections, but I still can't figure out how to use it when writing JS code.

For example, take this simple code that I wrote in jQuery that adds a suggestion window when a user types in an input field:

// this is the model var questions = [ {question: "what is your name"}, {question: "How old are you"}, {question: "what is your mothers name"}, {question: "where do work/or study"} ]; // search data function function searchData(datas,term){ return _.filter(datas, function(obj) { return ~obj.question.toLowerCase().indexOf(term); }); } // Events $("#suggestinput").on({ keyup: function(){ var results = searchData(questions, this.value); $("#suggestions") .addClass("active") .html(_.reduce(results, function(last, q){ return last + "<p>" + q.question + "</p>"; }, "")); }, blur: function () { $("#suggestions").removeClass('active'); $("#suggestions").html(" "); }, focus: function () { if ( $(this).val() === "" ) { $("#suggestions").addClass('active'); $("#suggestions").html("<p> start typing a question </p>"); } } }); 

Any tips on creating a mini-feature like this using the Backbone.js framework? I am not saying to write all the code, just a rough recommendation or explanation would be greatly appreciated.

There is also a working example of this code in JSFiddle: http://jsfiddle.net/X8geT/1/

+2
javascript jquery model-view-controller
source share
1 answer

Disclaimer: like any solution in Backbone, there are several ways to solve this problem, the next answer is probably overdoing it and should be taken with all due care.

Define your models

They will represent your data and how they should be processed. Here I define a question model (empty, but you never know), a collection of questions (where filtering is defined for a specific term), and a search state controller that is responsible for saving the current term and related questions:

 var Question = Backbone.Model.extend(); var Questions = Backbone.Collection.extend({ model: Question, matches: function (term) { if (term==="") return []; term = term.toLowerCase(); return this.filter(function(model) { return model.get('question').toLowerCase().indexOf(term)!==-1 }); } }); var QuestionController = Backbone.Model.extend({ defaults: { term: "" }, initialize: function(opts) { this.questions = opts.questions; //known questions this.matches = new Questions(); //filtered questions //when the term changes, update the matches this.on('change:term', function (model, term) { this.matches.reset(this.questions.matches(term)); }, this); } }); 

Define your views

They will display the state of models in the DOM and will handle user interactions. Suppose you have a SearchView that will process input and offers that will display current offers:

 var SearchView = Backbone.View.extend({ events: { 'keyup ': function (e) { this.model.set('term', this.$el.val()); }, 'focus ': function (e) { this.trigger('start'); }, 'blur ': function (e) { this.trigger('stop'); } } }); var SuggestionsView = Backbone.View.extend({ initialize: function () { _.bindAll(this, 'activate', 'deactivate', 'render'); this.listenTo(this.model.matches, 'reset', this.render); }, activate: function () { this.$el.addClass('active'); this.render(); }, deactivate: function () { this.$el.removeClass('active'); this.$el.html(" "); }, render: function () { var html = ''; if (this.model.get("term") === "") { html = "<p> start typing a question </p>"; } else { if (this.model.matches.length === 0) { html = "<p> No match </p>"; } else { this.model.matches.each(function(model) { html += '<p>'+model.get('question')+'</p>'; }); } } this.$el.html(html); } }); 

Bring models and views together

Run, bind events and run things

 var questions = new Questions([ {question: "what is your name"}, {question: "How old are you"}, {question: "what is your mothers name"}, {question: "where do work/or study"} ]); var controller = new QuestionController({ questions: questions }); var vSearch = new SearchView({ el: '#suggestinput', model: controller }); var vSuggestions=new SuggestionsView({ el: '#suggestions', model: controller }); vSuggestions.listenTo(vSearch, 'start', vSuggestions.activate); vSuggestions.listenTo(vSearch, 'stop', vSuggestions.deactivate); 

And a script to play with http://jsfiddle.net/nikoshr/QSE95/

Of course, you could greatly simplify this by having a single type of processing for all interactions, but where would it be fun?

+4
source share

All Articles