New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support Asynchronous Module Loading (require.js) #57
Comments
I'm happy to help with this if there are questions. In particular, there are some notes on updating existing libraries, and the guidance for these higher level libraries is to use an anonymous define call. Also, since this library does not need root/window global (all that is done in this registration block), then the code can be reduced to: (function(root, factory) {
// Set up appropriately for the environment.
if (typeof exports !== 'undefined') {
// Node/CommonJS
factory(exports, require('underscore'), require('backbone'));
} else if (typeof define === 'function' && define.amd) {
// AMD
define(['exports', 'underscore', 'backbone'], factory);
} else {
// Browser globals
factory({}, root._, root.Backbone);
}
}(this, function(exports, _, Backbone) {
// Backbone.Relational extensions to Backbone
// NOTE: the few lines assigning the exports, _, and Backbone are no longer needed
})); |
Wow, that piece of code looks seriously arcane, takes a few moments to wrap your head around ;). Relational does need access to |
I have managed to avoid |
Doesn't it already do that? First, if ( typeof window === 'undefined' ) {
_ = require( 'underscore' );
Backbone = require( 'backbone' );
exports = module.exports = Backbone;
} Then it attempts to find models (if their name is given as a string) on the exports var (which is currently either /**
* Find a type on the global object by name. Splits name on dots.
* @param {string} name
*/
getObjectByName: function( name ) {
var type = _.reduce( name.split( '.' ), function( memo, val ) {
return memo[ val ];
}, exports);
return type !== exports ? type: null;
}, |
Yes, root in the snipped I posted is "window" in a browser context. A side note on this line from your latest code post:
Doing |
There is an order's error in the module dependency array ( jrburke first comment): define(['underscore', 'backbone', 'exports'], factory); Should be: define(['exports', 'underscore', 'backbone'], factory); |
@carlosjavier84 ah yes! Thanks for the catch. I have edited my comment above to reflect your comment. |
This isn't an issue per se. I've built a project with requirejs and backbone-relational and i've run into an annoying issue i've had to poorly hack around. When defining the models relations, more specifically reverse relations collection, you'll run into circular dependencies that requirejs doesn't like. define('models/user', function(require) {
var Backbone = require('backbone');
return Backbone.RelationalModel.extend({});
});
define('collections/users', function(require) {
var Backbone = require('backbone');
return Backbone.Collection.extend({
model: require('models/user')
});
});
define('models/todo', function(require) {
var Backbone = require('backbone');
return Backbone.RelationalModel.extend({
relations: [{
type: Backbone.HasOne,
key: 'user',
relatedModel: require('models/user'),
reverseRelation: {
key: 'todos',
collectionType: require('collections/todos') // Circular
}
}]
});
});
define('collections/todos', function(require) {
var Backbone = require('backbone');
return Backbone.Collection.extend({
model: require('models/todo') // Circular
});
}); requirejs can make circular dependencies immediately available through exports but that doesn't play nice with backbone's factory functions for models and collections. @jrburke correct me if I'm wrong. |
I've come up with a workaround for now. That is to simply not use HasMany reverse relations when using requirejs modules. |
Sorry for leaving this unattended, but unfortunately I don't think it's worth it to add this to Backbone-relational at the moment, seeing the stance of Underscore and Backbone on this issue. If both implemented this, something would be gained by adding it here as well; as it is, that's not so much the case.. @amccloud apparently, trying to find an object on |
What might be nice is if collectionType could accept a function that is called when an instance is actually created, so for @amccloud's example above: collectionType: function () {
return require('collections/todos');
} caveat: I'm just going off a hazy memory of the problem and the code above, @amccloud may be able to test to confirm. |
I understand that integration of this is not going to happen in the foreseeable future, but if someone has a patch to enable method support for the model references, I'd be interested... |
Please see #127. If you have more experience with these environments than me, that would probably help a lot ;). |
"exports = module.exports = Backbone;" is not compatible with require.js |
Superseded by #215. |
This is becoming more and more an accepted practice. jQuery 1.7 and even jQuery Mobile (in a branch) are supporting Asynchronous Module Loading. I have modified a copy of backbone-relational.js to employ a method which @jrburke implements here: https://github.com/jrburke/backbone/tree/optamd3. For this project:
I have not tested this in Node, nor without Require.js.
The text was updated successfully, but these errors were encountered: