大型backbone.js网络应用程序组织

use*_*480 61 javascript jquery namespaces organization backbone.js

我目前正在开发一个基于backbone.js构建的大型Web应用程序,并且在组织,"僵尸"等方面遇到了很多问题.所以我决定做一个主要的代码重构.我已经编写了一堆辅助函数来处理"僵尸"; 但是,我想从一开始就为代码创建一个很好的结构/组织.我没有在大型的backbone.js组织上找到很多很棒的教程/示例,所以我从头开始,想看看我是否可以就我开始的地方得到一些意见.

我显然在全局命名空间中设置了我的代码; 但我也想保持这个命名空间相当干净.我的主要app.js使类文件本身与全局命名空间分开; 您可以使用reg()函数注册一个类(以便可以实例化它),而inst()函数可以从classes数组中实例化一个类.因此,除了3种方法之外,MyApp命名空间只有路由器,模型和视图:

var MyApp = (function () {

    var classes = {
        Routers: {},
        Collections: {},
        Models: {},
        Views: {}
    };

    methods = {

        init: function () {
            MyApp.Router = MyApp.inst('Routers', 'App');
            MyApp.Model = MyApp.inst('Models', 'App');
            MyApp.View = MyApp.inst('Views', 'App');
            Backbone.history.start();
        },

        reg: function (type, name, C) {
            classes[type][name] = C;
        },

        inst: function (type, C, attrs) {
            return new classes[type][C](attrs || {});
        }

    };

    return methods;

}());

$(MyApp.init);
Run Code Online (Sandbox Code Playgroud)

在模型,集合,路由器和视图中,我像往常一样工作,但是然后需要在文件的末尾注册该类,以便可以在以后实例化它(不会使命名空间混乱):

MyApp.reg('Models', 'App', Model);
Run Code Online (Sandbox Code Playgroud)

这似乎是组织代码的不必要的方式吗?其他人是否有更好的例子来说明如何使用许多路由器,集合,模型和视图组织真正的大型项目?

nra*_*itz 32

我最近在弄称为GapVis骨干项目(这里的代码,这里呈现的内容).我不知道它是否"非常大",但它是大而且相对复杂 - 24个视图类,5个路由器等等.虽然我不知道我的所有方法都是相关.你可以在我的主app.js文件中看到我的一些想法.一些关键的架构选择:

  • 我有一个State包含所有当前状态信息的单例模型 - 当前视图,我们正在查看的模型ID等等.每个需要修改应用程序状态的视图都通过设置属性State以及需要响应的每个视图来实现到州听这个模型的事件.对于修改状态和更新的视图尤其如此 - UI事件处理程序events永远不会重新呈现视图,而是通过将呈现函数绑定到状态来完成.这种模式确实有助于保持视图彼此分离 - 视图从不在另一个视图上调用方法.

  • 我的路由器被视为专用视图 - 它们通过更新状态来响应UI事件(即键入URL),并通过更新UI(即更改URL)来响应状态更改.

  • 我做了几件类似于你提议的事情.我的命名空间有一个init类似于你的命名空间,以及一个settings常量对象.但我也将大部分模型和视图类放在命名空间中,因为我需要在多个文件中引用它们.

  • 我为我的路由器使用了一个注册系统,并考虑了一个用于我的视图,这是保持"主"类(AppRouterAppView)不必知道每个视图的好方法.AppView但是,在这种情况下,事实证明,子视图的顺序非常重要,因此我最终对这些类进行了硬编码.

我几乎不会说这是做事的"正确"方式,但它对我有用.我希望这很有帮助 - 我也很难找到使用Backbone的大型项目的可见源代码示例,并且随着我的进展不得不解决大部分问题.


小智 13

这2个资源帮助我在坚实的地下室设置我的骨干应用程序:


Mau*_*ord 5

命名空间类似于你正在做的事情(至少对于类部分而言),我的所有模型,视图和控制器都是这样的:

意见/ blocks.js:

(function(cn){
    cn.classes.views.blocks = cn.classes.views.base.extend({

        events: {},

        blocksTemplate: cn.helpers.loadTemplate('tmpl_page_blocks'),

        initialize: function(){
        },

        render: function(){
            $(this.el).html(this.blocksTemplate());
        },

        registerEvents: function(){},
        unregisterEvents: function(){}
    });
})(companyname);
Run Code Online (Sandbox Code Playgroud)

我的JavaScript命名空间看起来像这样,尽管我每次构建新应用程序时都会改进它:

 companyname:{                                                                                                                                                                                 
   $: function(){},      <== Shortcut reference to document.getElementById                                                                                                                      
   appView: {},          <== Reference to instantiated AppView class.                                                                                                                           
   classes = {           <== Namespace for all custom Backbone classes.                                                                                                                         
     views : {},                                                                                                                                                                                
     models : {},                                                                                                                                                                               
     collections: {},                                                                                                                                                                           
     controllers : {},                                                                                                                                                                          
     Router: null                                                                                                                                                                               
   },                                                                                                                                                                                           
   models: {},          <== Instantiated models.                                                                                                                                                
   controllers: {},     <== Instantiated controllers.                                                                                                                                           
   router: {},          <== Instantiated routers.                                                                                                                                               
   helpers: {},         <== Reusable helper platform methods.                                                                                                                                   
   currentView: {},     <== A reference to the current view so that we can destroy it.                                                                                                          
   init: function(){}   <== Bootstrap code, starts the app.                                                                                                                           
 } 
Run Code Online (Sandbox Code Playgroud)

我希望我的所有观点都有,我把它放在基本视图中.我的控制器将调用registerEvents它创建的任何新视图(渲染后)和unregisterEvents视图,然后再杀死它.并非所有视图都有这两个额外的方法,所以它首先检查是否存在.

不要忘记所有视图都带有this.el.remove();内置.这不仅会杀死视图容器元素,还会取消绑定附加到它的所有事件.根据您通过控制器创建视图的方式,您实际上可能不想杀死该元素并执行this.el.unbind()而不是取消绑定所有事件.

  • `.remove`会自动执行`.unbind`,所以你应该好. (2认同)

Jus*_*ong 5

事实上,以不同的方式有不同方式的优点和缺点.最重要的是找到一种合适的文件组织方式.以下是我目前正在进行的项目的组织.这种方式的重点是将相同的模块相关文件放在一个文件夹中.例如:people模块,这个模块的所有文件都放在modules/base/people目录下.更新和维护这个模块后,只需要关注此目录中的文件就行了,不会影响目录外的文件,并提高了可维护性.

我希望我的回答可以给你一些帮助,我希望你有一些宝贵的建议.

在此输入图像描述