如何通过backbone.js中的全局变量创建集合?

Sea*_*Sin 0 javascript backbone.js

我在stackoverflow中得到了许多顾问的帮助,部分问题已经解决,但仍然存在一些问题.

我咨询了答案,我试图解决问题,因为它我理解了javascript命名空间pattren.

一种命名空间模式,可避免污染全局命名空间.
有关此命名空间模式的更多详细信息
如何在JavaScript中声明命名空间?

我遇到了成功创建全局变量的问题,但我没有处理生成的变量.

collecton.js

    var app = app || {};
(function () {
    'use strict';
    var collections = app.Collection = app.Collection || {};

    collections.VideoLists =  Backbone.Collection.extend({
        model: app.Model,
        initialize: function(){
            console.log('load Collection');
        }
    });

    app.Collection = collections.VideoLists;
})();
Run Code Online (Sandbox Code Playgroud)

model.js

var app = app || {};
(function() {
    'use strict';
    var models = app.Model = app.Model || {};

    models.Video = Backbone.Model.extend({
        initialize: function(){
            console.log('model create');
        },
        defaults:{
                 id : "1",
                 url : "/assets/videos/call/MOV01718.mp4",
                 imgSrc : "assets/img/call/1_thumbnail.png",
                 title: "call situation conservation"
        }
    });
  app.Model = new models.Video();
})();
Run Code Online (Sandbox Code Playgroud)

router.js

listRoute: function(id) {
          //generate the collection using the listsection
          var videoList = this.collection;
          var getId = parseInt(id);
            switch (getId) {
              case 1:
                new videoList([
                    {
                      id : "1",
                      url : "/assets/videos/call/MOV01718.mp4",
                      imgSrc : "assets/img/call/1_thumbnail.png",
                      title: "call situation conservation"
                    },
                    {
                      id : "2",
                      url : "/assets/videos/call/MOV01722.mp4",
                      imgSrc : "assets/img/call/2_thumbnail.png",
                      title: "call situation conservation"
                    }
                  ]);
                break;

  //app.router init part
  initialize: function() {
            // create the layout once here
            this.layout = new views.Application({
                el: 'body',
            });
            // create model and collection once here
            this.model = app.Model;
            this.collection = app.Collection;
        }
Run Code Online (Sandbox Code Playgroud)

请看下面的图片 在此输入图像描述

我认为这一代人已经做得很好.
但我不明白为什么我会收到这个错误.

我在第一步尝试
1.不要生成集合new function(作为当前的源代码)
2.创建变量videoList作为对象.
3.存储Collection在变量中.
4.使用collection.create函数.
例如,list.create({id:'dasdsad'});

然而,这种尝试最终产生了相同的结果.
我该如何解决?

Emi*_*ron 5

命名空间模式的目的是什么?

您正在滥用命名空间模式.这种情况下的目标是将所有自定义Backbone类构造函数命名为app对象.

为了使所有内容清楚地分开,将所有集合构造函数放入app.Collection对象,模型构造函数app.Model等中.

如果app在创建所有类之后检查命名空间,它应如下所示:

var app = {
    Collection: {
        VideoList: /* video list constructor */
    },
    Model: {
        Video: /* video model constructor */
    },
    View: {
        /* same thing goes for views */
    }
};
Run Code Online (Sandbox Code Playgroud)

app命名空间不应1包含实例,主要是构造函数.

不要覆盖构造函数引用:

app.Model = new models.Video();
Run Code Online (Sandbox Code Playgroud)

当您只需要一个实例时创建一个实例,并将其保留在所需的范围内.

this.model = new app.Model.Video();
this.collection = app.Collection.VideoList();
Run Code Online (Sandbox Code Playgroud)

实例和构造函数

要真正理解前一点,您需要了解构造函数和实例之间的差异.该概念适用于其他OOP语言,但我会将描述保留在JavaScript语言细节中.

构造函数只是一个函数.来自MDN docObject.prototype.constructor:

所有对象都有一个constructor属性.

[...]

以下示例创建一个原型,Tree以及该类型的对象theTree.

function Tree(name) {
  this.name = name;
}

var theTree = new Tree('Redwood');
Run Code Online (Sandbox Code Playgroud)

如前面的示例所示,要创建实例,请使用new运算符.JavaScript中的'new'关键字是什么?

new运算符创建用户定义的对象类型的实例或具有构造函数的内置对象类型之一.

new constructor[([arguments])]
Run Code Online (Sandbox Code Playgroud)

通过创建自定义构造函数,您可以定义自定义类型(类).有多种方法可以在JavaScript中创建更复杂的自定义类型,但这是另一种讨论.有关更多详细信息,请参阅如何在JavaScript中"正确"创建自定义对象?

幸运的是,Backbone提供了一种简单(自以为是)的方式来定义新类型,即extend函数,它可以在所有Backbone的基类型上使用.

var ModelConstructor = Backbone.Model.extend({ /*...*/ });

var modelInstance = new ModelConstructor();
Run Code Online (Sandbox Code Playgroud)

注意,myVariable = MyConstructor只是将构造函数的引用传递给myVariable它,它不会创建新的实例.你仍然可以使用变量作为构造函数.

var myInstance = new myVariable();
Run Code Online (Sandbox Code Playgroud)

订购和依赖

如果查看代码,您会注意到app.Collection.VideoList该类使用app.Model.Videomodel属性作为值.

这意味着app.Collection.VideoList取决于app.Model.Video类的可用性.因此,应该在模型文件之后将集合文件插入到文档中.

就像在我的另一个答案中你所链接的那样:

<script src="js/models/todo.js"></script><!-- no dependencies -->
<script src="js/collections/todos.js"></script><!-- depends on the model -->
<script src="js/views/todo-view.js"></script><!-- depends on the collection and the model -->
<script src="js/views/app-view.js"></script><!-- depends on the todo-view -->
<script src="js/routers/router.js"></script><!-- depends on the app view -->
<script src="js/app.js"></script><!-- depends on the router -->
Run Code Online (Sandbox Code Playgroud)

1. app如果要在所有应用程序(如单例,命名空间全局或服务)之间共享,则命名空间对象可以包含对象的实例.