将您的jQuery代码转换为Backbone.js结构

我对Backbone.js很赞,但我喜欢jQuery。 但是我喜欢Backbone如何将代码组织到模型,视图和集合中,但我仍然无法理解在编写JS代码时如何使用它。

例如,我在jQuery中编写这个简单的代码,当用户键入输入框时,它会附加一个建议框:

// 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 + "

" + q.question + "

"; }, "")); }, blur: function () { $("#suggestions").removeClass('active'); $("#suggestions").html(" "); }, focus: function () { if ( $(this).val() === "" ) { $("#suggestions").addClass('active'); $("#suggestions").html("

start typing a question

"); } } });

有关使用Backbone.js结构构建这样的迷你function的任何建议吗? 我不是说编写整个代码,只是粗略的指导方针或解释将非常感激。

在JSFiddle上还有一个这个代码的工作示例: http : //jsfiddle.net/X8geT/1/

免责声明 :作为Backbone中的任何解决方案,有多种方法可以处理给定的问题,以下答案可能完全矫枉过正,应该采取一切应有的谨慎态度。

定义模型

它们将代表您的数据以及如何处理它们。 在这里,我将定义一个问题模型(空,但你永远不知道),一个问题集合(定义了一个术语的过滤),以及一个负责存储当前术语和匹配问题的搜索状态控制器:

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

定义您的视图

它们将在DOM中显示模型的状态,并将处理与用户的交互。 让我们有一个将处理输入的SearchView和一个将显示当前建议的SuggestionsView:

 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 = "

start typing a question

"; } else { if (this.model.matches.length === 0) { html = "

No match

"; } else { this.model.matches.each(function(model) { html += '

'+model.get('question')+'

'; }); } } this.$el.html(html); } });

将模型和视图结合在一起

实例化,绑定事件和运行事物

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

和http://jsfiddle.net/nikoshr/QSE95/一起玩的小提琴

当然,您可以通过处理所有交互的单个视图来大大简化这一过程,但哪里会很有趣?