0

我的 Backbone 项目发生了一些奇怪的事情。我正在将它重建为 AMD,我必须更改一些变量名才能让它再次工作。我有一个要传递给视图console.log的集合,但是当我收集时,我得到了对象和 null。

这是我的看法:

define([
    'jquery',
    'underscore',
    'backbone',
    'models/tableModel',
    'collections/tablesCollection',
    'views/tablesView',
    'views/tableView'
],
function($, _, Backbone, tableModel, tablesCollection, tableView) {
    var tv = Backbone.View.extend({
        tagName: 'div',
        initialize: function() {
            console.log(this.collection);
            this.collection.on('reset', this.render, this);
            this.template = this.options.template;
            this.url = this.collection.url;

        },
        render: function() {
            //tablesCollection.collection.each(this.addOne, this);
            return this;
        },
        addOne: function(model) {
            var t = new tableView({ model: model, template: this.template, url: this.url });
            this.$el.append(t.render().el);
            return this;
        },
        stripQueryString: function(url) {
            return url.split('?')[0];
        }
    });

    return tv;
});

您将在项目中看到 console.log 几行。这是我在 Firebug 中得到的结果:

在此处输入图像描述

两者都引用相同的行号。这是对象中的内容:

在此处输入图像描述

这里发生了什么?为什么我会为同一件事得到两个结果?其中一个是我想要的,另一个不是。

编辑:这是我实例化视图的地方:

define([
    'jquery',
    'underscore',
    'backbone',
    'models/tableModel',
    'collections/TablesCollection',
    'views/tablesView',
    'views/tableView'
], function($, _, Backbone, TableModel, tablesCollection, tablesView, tableView) {
    var t = new tablesCollection(null, { url: 'main-contact'} );
    var tables = new tablesView({ collection: t, template: 'main-contact-template'});
    $('#web-leads').html(tables.render().el);

});

这是我的收藏:

define([
    'jquery',
    'underscore',
    'backbone',
    'models/tableModel'
],
function($, _, Backbone, tableModel) {
    var tablesCollection = Backbone.Collection.extend({
        url: this.url,
        model: tableModel,
        initialize: function(models, options) {
            if (options && options.url) {
                this.url = options.url;
            }
            this.fetch({
                success: function(data, options) {

                }
            });
        }
    });

    return tablesCollection;
});

另外两个文件:

// Filename: app.js
define([
    'jquery',
    'underscore',
    'backbone',
    'router' // Request router.js
], function($, _, Backbone, Router){
    var initialize = function(){
    // Pass in our Router module and call it's initialize function
    Router.initialize();
};

return {
    //initialize: initialize  <--This is where the second init call was happening.
};
});

主.js:

 require.config({
        paths: {
            //jquery: 'libs/jquery/jquery-1.8.3.min',
            underscore: 'libs/underscore/underscore-min',
            backbone: 'libs/backbone/backbone-min'
        }
    });

    if ( typeof define === "function" && define.amd && define.amd.jQuery ) {
      define( 'jquery', [], function () { return jQuery; } );
    }

    //the "main" function to bootstrap your code
    require(['jquery', 'underscore', 'backbone', 'app'],
        function () {
            var App = require('app');
            App.initialize();
            // console.log($);
            // console.log(_);
            // console.log(Backbone);
    });
4

1 回答 1

0

您之前的代码版本比这个编辑的版本更有意义,因为在之前的版本中,您实际上是推送到console.log给问题的对象

// contents of 'that/view/that/gives/me/problems.js'
define([
    'jquery',
    'underscore',
    'backbone',
    'models/tableModel',
    'collections/tablesCollection',
    'views/tablesView',
    'views/tableView'
],
function($, _, Backbone, tableModel, tablesCollection, tableView) {
    console.log("factory", tablesCollection.collection); // <- you did not have this line. my addition
    var tv = Backbone.View.extend({
        tagName: 'div',
        initialize: function() {
            console.log("init", tablesCollection.collection); // <- your prior version. Point of your error
            this.collection.on('reset', this.render, this);
            this.template = this.options.template;
            this.url = this.collection.url;

        }
        // ...
    });

    return tv;
});

现在你让它显示两次的原因是因为你在上面定义的视图在某处被初始化了两次

第一次初始化时,它会显示您所看到的值。指针周围的第二次tablesCollection被某些东西清理了,因此,您遇到了该错误。

现在清理了什么tablesCollection以及为什么我在您提供的代码中看不到任何地方。它可能与在代码中某处重新需要“collections/tablesCollection”模块有关。正如我从您的“collections/tablesCollection”模块代码中看到的那样,您在每次工厂调用时都重新定义了输出。我要做的是计算一次并缓存服务:

// contents of 'collections/tablesCollection.js'
;(function(){

    var mythings = {}

    function initializer($, _, Backbone, tableModel){
        return Backbone.Collection.extend({
            url: 'url',
            model: tableModel,
            initialize: function(models, options) {
                // ...
            }
        });
    }

    define([
        'jquery',
        'underscore',
        'backbone',
        'models/tableModel'
    ],
    function($, _, Backbone, tableModel) {
        if (!mythings.tablesCollection){
            // this will be done on first run.
            mythings.tablesCollection = initializer($, _, Backbone, tableModel)
        }
        // all others will just return same exact instance of collection class
        return mythings.tablesCollection
    })

})();

编辑:

询问 AMD 规范组是否有可能在每次需要时重新运行“工厂”功能。即时回答是“不太可能”,但长期回答是“可能(如果以不同的名字询问)”

我在上面的代码片段中添加了注释行,指示它们是什么文件。

我还在第一个片段中添加了一个 console.log 行,它应该可以帮助您了解您遇到的问题与 AMD 加载程序无关。您只需在某处将视图初始化两次。

当您使用顶部代码段中的注释行运行代码时,您将看到factory日志行仅显示一次并显示init两次,就像在您的原始错误屏幕截图中一样。

您需要跟踪使用该tv变量中返回的视图的位置。您正在启动它两次。

至于在第二次运行中(清除)引用会发生什么,tablesCollection我不知道也看不到您提供的片段中的任何地方。

于 2013-01-26T22:48:49.623 回答