问题
Something odd is going on with my Backbone project. I'm rebuilding it as AMD and I'm having to change some variable names to get it working again. I have a collection I'm passing into a view, but when I console.log
the collection, I get both the object and null.
Here is my view:
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;
});
You'll see the console.log several lines down in the project. Here is what I get in Firebug as a result:

Both cite the same line number. Here is what's in the object:

What is going on here? Why am I getting two results for the same thing? One of them is what I want and the other one isn't.
EDIT: Here is where I instantiate the view:
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);
});
Here is my collection:
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;
});
Two other files:
// 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.
};
});
Main.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);
});
回答1:
You prior version of the code made more sense than this edited version, as in the prior version you were actually pushing to console.log
the object that was giving trouble
// 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;
});
Now the reason you have it show up twice is because the view you define above is initialized twice somewhere.
First time it's initialized it shows the value as you can see. The second time around the pointer tablesCollection
is cleaned up by something and, hence, you have that error.
Now what cleans up tablesCollection
and why I don't see anywhere in the code you present. It has likely something to do with re-requiring 'collections/tablesCollection' module somewhere in your code. As I can see from your 'collections/tablesCollection' module code, you REDEFINE the output on every factory call. What I would do is calc it once and serve cached:
// 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
})
})();
EDIT:
Asked the AMD spec group if there is a chance of 'factory' function rerunning on every require. Immediate answer was "Not likely" but long term answer is "Possible (if asked under different name)"
I added comment lines to the code snippet above indicating what files they are.
I also added a console.log line in the first snippet that should help you understand that the issue you have is NOT with AMD loader. You simply initialize the view twice somewhere.
When you run the code with comment lines like in the top snippet you will see factory
log line shoing up only once and init
line twice, like in your origianl error screenshot.
You need to trace where you use the view returned in that tv
variable. You are initing it twice.
As to what happens to (what clears) reference to tablesCollection
in the second run I don't know and don't see anywhere in the snippets you provided.
来源:https://stackoverflow.com/questions/14512551/backbone-console-log-returning-collection-and-undefined