javascript – Backbone.js:模型,集合,路由器,何时以及为何?

我仍然试图绕过Backbone.js
我看了一些截屏并阅读了一些教程.我也是RTFM.但是,我对每个人似乎都在使用框架的某些部分来处理不同的任务感到困惑.

在使用传统的待办事项列表应用程序后,我决定在真实的应用程序中首次拍摄backbone.js.

我的应用程序将收到一个充满问题的JSON对象.然后,我喜欢有一个’ul’,我可以在那里移动这些问题(下一个q,前一个q).我已经有了一个显示按钮的视图,并在用户点击“下一个”或“上一个”时发出通知.我的问题是:我应该在哪里处理我的’currentQuestion’,’next’和’previous’功能的逻辑.我见过一些人使用Collection这个,还有一些人使用Model.这让我很困惑.

任何人都可以指出一些元代码来处理这个问题?非常感谢!

这个问题没有真正正确的答案.肯定有不止一种方法可以使它工作,这是关于Backbonejs的一个好处:它非常灵活,并没有对你施加太多的设计选择.

如果我要开始构建你所描述的内容,我肯定会:

>问题模型
>一个问题集
>一个用于呈现单个问题的QuestionView
>一个QuestionsIndexView,用于显示问题列表

在那之后,事情变得有点模糊,这取决于您对应用程序的要求.如果您希望状态像传统网站一样存储,您可以使用路由器并执行类似下面的操作:

ApplicationRouter = Backbone.Router.extend({

    routes: {
       "": "index",
       "question/:id": "show"
    },

    index: function() {
        // render a QuestionsIndexView...
    },

    show: function(id) {
        // find the q and render a QuestionView...
    }
 })

这很好,因为状态是在URL中维护的,因此用户可以使用浏览器前进和后退按钮,事情可能会像他们期望的那样工作.这个问题是,我们如何使nextQuestion和previousQuestion按钮工作?

如果您将它们作为QuestionView的一部分,则问题必须知道其下一个和之前的问题是什么.您可能想出一个方案来完成这项工作,但更优雅和经常使用的模式是创建另一个模型,它存在于我们已经提到的已经称为App的所有数据模型之上,然后生成这个的QuestionsCollection和current_question_id属性模型.然后我们将在路由器方法中更新此current_question_id attr.

现在我们正在烹饪,我们的应用程序状态不仅存在于浏览器的URL中,而且还作为可观察对象存在于应用程序层.我们可以轻松创建一个ButtonsPanelView,它会传递此App模型,并在单击其按钮时触发正确的路径.在App模型中实现hasNextQuestion和hasPreviousQuestion并使用它来在用户无法前进或前进时切换或禁用相应的按钮也是微不足道的.

按要求编辑:

要使存在于其他所有内容之上的App模型非常简单.您可能已经在某处看起来像这样的代码:

window._qs = new Questions();
window._qs.fetch();

只需这样做:

var qs = new Questions();
window.app = new App({questions: qs});
qs.fetch();

现在是问题集合是应用程序模型的一个属性,正如我们想要的那样.那么App的定义是什么样的呢?同样,有很多方法可以解决这个问题,但我喜欢使用Backbone.Models’s validate以确保我不会陷入糟糕的状态.这是我可能做的:

App = Backbone.Model.extend({

   defaults: {
      current_question_index: 0
   },

   validate: function(attrs) {

      if(typeof attrs.current_question_index !== "undefined") {
         // we are trying the change the question index,
         // so make sure it is valid
         var len = this.get("questions").length
         if(attrs.current_question_index < 0 || attrs.current_question_index >= len) {
            // returning anything prevents invalid set
            return "index is out of bounds"; 
         }
      }
    },

    hasNextQ: function() {
      var next_ind = this.get("current_question_index") + 1;
      // use the logic we already created, in validate() but
      // convert it to a bool. NOTE in javascript:
      //       !"stuff"   === false
      //       !undefined === true 
      return !this.validate({current_question_index: next_ind}); 
    },

    nextQ: function() {
      var next_ind = this.get("current_question_index") + 1;
      // validate() will prevent us from setting an invalid index
      return this.set("current_question_index", next_ind);

    }

});
相关文章
相关标签/搜索