在backbone.js中使用全局变量。最佳实践

时间:2012-05-09 15:44:33

标签: javascript backbone.js

也许只是一个愚蠢的问题 在所有示例中,我都看到视图模型和集合是全局变量 这里有一个例子。 introduction-to-backbone
可以在不使用全局变量或命名空间的情况下定义模型视图和集合吗? 然后我该如何访问它们?

2 个答案:

答案 0 :(得分:2)

您可以在任意位置定义模型和集合(及其各自的实例)。我会为模型等推荐某种全局命名空间约定,只是为了重用。一个简单的方法是:

window.ProjectModels = window.ProjectModels || {};  //use existing namespace  or create a new one.
ProjectModels.SomeModel = Backbone.Model.extend({ ...});
ProjectModels.SomeOtherModel = Backbone.Model.extend({ ...});
ProjectModels.SomeRelatedModel = ProjectModels.SomeModel.extend({ ...});
...
window.ProjectViews = window.ProjectViews || {};  //use existing namespace  or create a new one.
ProjectViews.SomeModelView = Backbone.View.extend({ ...});
ProjectViews.SomeOtherModelView = Backbone.View.extend({ ...});
ProjectViews.SomeRelatedModelView = ProjectViews.SomeModel.extend({ ...});

您可能想知道为什么我没有将集合放在他们自己的命名空间中。我没有将集合放在他们自己的命名空间中的唯一原因是我可以看到一些情况,我可能会将Backbone.Model扩展为某种层次集合/事物;我也可以将模型与集合区分开来,因为我有一个命名集合的常规[Something] Collection ...换句话说,我没有充分的理由,我只是按照我的口味去做。

答案 1 :(得分:2)

@JayC实际上对全局命名空间是正确的,并且存在某种命名空间约定,但我实际上喜欢为每个Backbone类使用单独的模块,并在以后使用一个(或者没有,如果你知道的话)加载它你正在做什么)命名空间。让我来看看使用CommonJS没有全局变量应用程序的例子(实际上有很好的资源如何使用RequireJS来实现它。)

您需要的是非常简单的附加库,看起来像gist。它基本上为您提供了CommonJS规范,可以用于单独的文件或缩小文件(例如script.js文件)。

假设您有4个文件,名称为:model.jscollection.jsview.jsapp.js,它们看起来像这样:

// model.js
this.require.define({'model.js': function(exports, require, module) {(function() {
    var MyModel = Backbone.Model.extend({
        ...
    });

    module.exports = MyModel;
}).call(this)}});

// collection.js
this.require.define({'collection.js': function(exports, require, module) {(function() {
    var MyCollection = Backbone.Collection.extend({
        model : require('model.js');
    });

    module.exports = MyCollection;
}).call(this)}});

// view.js
this.require.define({'view.js': function(exports, require, module) {(function() {
    var MyView = Backbone.View.extend({
        initialize: function() {
            var Collection = require('collection.js');
            this.collection = new Collection();
        }
    });

    module.exports = MyView;
}).call(this)}});

// app.js
this.require.define({'app.js': function(exports, require, module) {(function() {
    var View = require('view.js');

    $(function() {
        new View();
    });
}).call(this)}});    

html文件中的脚本标记应如下所示:

<script src='jquery-underscore-backbone.js'></script>
<script src='commonjs.js'></script> <!-- this is the library from the gist -->
<script src='model.js'></script>
<script src='collection.js'></script>
<script src='view.js'></script>
<script src='app.js'></script>

您可以缩小所有文件并仅使用所有这些文件的缩小内容加载一个文件(例如script.js),也可以使用。

通过这样做,你将没有全局命名空间,没有App.Class,没有App.Collection ......等等。如果你确定你在做什么,你甚至不必拥有{ {1}}变量。

我知道它看起来很难看,因为包装器,但是有自动包装它的框架或者如果你使用AJAX模块加载(requireJS),你将不需要使用这个包装函数。

这方面的好例子(node.js)是:Stich