4

我仍在尝试了解 Backbone.js 我已经观看了一些截屏视频并阅读了一些教程。我也是RTFM。但是,对于每个人似乎如何使用框架的某些部分来处理不同的任务,我有点困惑。

在玩过传统的待办事项列表应用程序之后,我决定在一个真正的应用程序中第一次尝试主干.js。

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

任何人都可以给我一些元代码来处理这个?非常感谢!

4

2 回答 2

7

这个问题真的没有一个正确的答案。肯定有不止一种方法可以让它工作,这是 Backbonejs 的优点之一:它非常灵活,不会强加给你太多的设计选择。

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

  • 一个Question模型
  • 一个Questions集合
  • aQuestionView用于呈现单个问题
  • aQuestionsIndexView用于显示问题列表

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

 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 中维护了状态,因此用户可以使用浏览器的前进和后退按钮,并且事情可能会按照他们的预期工作。问题是,我们应该如何让这些nextQuestionpreviousQuestion按钮工作?

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

现在我们真的在做饭,我们的应用程序状态不仅持久化在浏览器的 URL 中,而且还作为可观察对象存在于应用程序层。我们可以轻松创建一个ButtonsPanelView通过此App模型并在单击其按钮时触发正确路由的方法。当用户无法返回或前进时,在模型中实现hasNextQuestion和使用它或禁用相应的按钮也很简单。hasPreviousQuestionApptoggle

按要求编辑:

制作一个App高于一切的模型非常简单。您可能已经在某处有如下代码:

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

只需这样做:

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

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

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

    }

});
于 2012-05-04T07:52:32.580 回答
1

正如我在 BackboneJS 中所理解的那样,“模型”是一个数据单元。例如,“待办事项”的单元数据将包含:

  • 一个约会
  • 一个消息
  • 一种状态

这些数据单元存储在“集合”中。它们是包含“行”的“数据库表”的同义词。但是模型数据并不局限于像一行那样的二维。然后Backbone“视图”执行逻辑以及与界面交互 - 更像是“视图控制器”。视图包含事件处理程序、添加和删除元素的代码、更改界面等。

于 2012-05-04T07:49:47.157 回答