Backbone 子视图定义 - 主视图与路由器

Backbone sub views definition - main view vs router

这是我的 Backbone 路由器的样子

define([
    "jquery",
    "underscore",
    "backbone"
], function ($, _, Backbone) {

    return Backbone.Router.extend({
        routes: {
            "overview": "overview"
        },

        overview: function () {
            require([
                "views/overview",
                "models/user-collection",
                "grid",
                "spreadsheet"
            ], function (OverviewView, TestCollection, GridView, SpreadSheetView) {
                // Data
                var collection = new TestCollection();

                // Main view
                var view = new OverviewView({
                    el: "#page",
                    collection: collection
                });

                // Sub view #1
                var gridView = new GridView({
                    el: "#backgridWrapper"
                });

                // Sub View #2
                var spreadsheetView = new SpreadSheetView({
                    el: "#handsontableWrapper"
                });

                // Flow
                collection.fetch({
                    success: function () {
                        view.render();
                        gridView.render();
                        spreadsheetView.render();
                    }
                });

            });
        }
    });
});

如您所见,有几种观点:

  1. 主视图
  2. 子视图 #1
  3. 子视图 #2

我搜索了很多关于如何在 Backbone 中组织视图和子视图的方法,但是所有这些都应该直接在视图定义中创建一个新的子视图实例,所以该路由器只知道主视图...

所以问题是 - 在路由器而不是直接在视图构造函数处处理子视图是个好主意吗?

路由器应该只是处理路由和初始化东西。

像获取数据这样的事情应该放在使用它的视图中 - 视图显示数据或错误消息(以防失败),所以我认为让视图获取数据而不是某些路由器是明智的谁只对路线感兴趣,对数据不感兴趣。

我更喜欢在 parent 视图中初始化 sub 视图,而不是在其他地方。 parent - child 关系本身就证明了这一点,你最好让 children 和他们的 parents 在一起而不是陌生人,这样他们将受到更好的控制,您以后也可以轻松找到它们:)

主要是见仁见智,但问题是,如果您不这样做,您的所有代码很快就会在路由器中变得杂乱无章,而不是井井有条。

下面是我将如何构造相同的东西。

请注意,我正在初始化 child 视图作为 parent 视图渲染方法的一部分。它可以在初始化 parent 视图时完成,但我认为这样做没有意义,除非 parent 视图成功获取数据并继续呈现自身。

define([
  "jquery",
  "underscore",
  "backbone"
], function($, _, Backbone) {

  return Backbone.Router.extend({
    routes: {
      "overview": "overview"
    },
    overview: function() {
      require(["views/overview"], function(OverviewView) {
        // initialize Main view
        var view = new OverviewView({
          el: "#page"
        });
      });
    }
  });
});

define([
  "jquery",
  "underscore",
  "backbone",
  "models/user-collection",
  "grid",
  "spreadsheet"
], function($, _, Backbone, TestCollection, GridView, SpreadSheetView) {

  return Backbone.View.extend({
    initialize: function(options) {
      this.collection = new TestCollection();
      this.fetchData();
    },
    events: {},
    render: function() {
      // rendering subviews is part of rendering their parent view.
      //I prefer to do that here

      // Sub view #1
      this.gridView = new GridView({
        el: "#backgridWrapper"
      });
      // Sub View #2
      this.spreadsheetView = new SpreadSheetView({
        el: "#handsontableWrapper"
      });
     //Below lines can be handled while initializing the respective view 
     // (In their initialize() method, or after fetching some data etc
     // or can be chained with the above initialization if their render() method returns a reference to itself (`return this`)
      this.gridView.render();
      this.spreadsheetView.render();
    },
    fetchData: function() {
      var view = this;
      this.collection.fetch({
        success: function() {
          view.render();
        }
      });
    }
  });
});

旁注:我强烈建议不要将 collection 放在 models 文件夹下。