theironcook / Backbone.ModelBinder

Simple, flexible and powerful Model-View binding for Backbone.
1.42k stars 159 forks source link

CollectionBinder breaks RequireJS configuration? #221

Closed khcoder closed 9 years ago

khcoder commented 9 years ago

After adding CollectionBinder to a project that uses RequireJS, I'm getting two RequireJS errors related to Backbone.ModelBinder. I'm guessing I've missed something pretty basic, but can't seem to root this out:

First Error: A GET failure (not sure why it is looking in this directory since I've defined Backbone.ModelBinder in the /scripts/libs directory): http://localhost:55751/WebApp/scripts/Backbone.ModelBinder.js

Second Error: Uncaught Error: Script error for: Backbone.ModelBinder

Up to this point, ModelBinder has worked flawlessly with the project when loaded with RequireJS. When CollectionBinder is added to the 'define' array inside BaseView.js, RequireJS suddenly is looking in the wrong directory for Backbone.ModelBinder (not searching in /libs). If I take the Backbone.CollectionBinder out of my BaseView.js 'define' array, ModelBinder works just fine.

My files are organized as follows:

index.html - The RequireJS bootstrap in the index.html file:

<script data-main="scripts/config" src="scripts/libs/require.js"></script>

config.js - Notice that that ModelBinder and CollectionBinder are located in a sub-directory "scripts/libs" directory...not the base folder "scripts". So, not sure why RequireJS begins looking in looking in the base folder /scripts when CollectionBinder is added to my BaseView.

//Configure require.js
require.config({
    paths: {
        jquery: 'libs/jquery',
        underscore: 'libs/underscore',
        backbone: 'libs/backbone',
        modelbinder: 'libs/Backbone.ModelBinder',
        collectionbinder: 'libs/Backbone.CollectionBinder',
        text: 'libs/text',
        js_cookie: 'libs/js_cookie',    //For handling cookies for user session management
        usermodel: 'modules/auth/usersession/UserModel',
        session:   'modules/auth/session/SessionModel',
        handlebars: 'libs/handlebars',
        bootstrap: 'libs/bootstrap',
        parsley: 'libs/parsley',
    },
    // Dependencies for files and AMD shims:
    shim: {
        'parsley': { deps: ['jquery'] },
        'bootstrap': { deps: ['jquery'] } 
    }
});

BaseView.js - where the dependencies get loaded for the first time. If I remove collectionbinder from the 'define' array, then I have no errors and ModelBinder works as expected. (NOTE - I haven't finished the implementation of the collectionbinder, so please disregard the commented-out code for now).

define([
    'jquery',
    'underscore',
    'backbone',
    'modelbinder', 
    'collectionbinder'
], function($, _, Backbone, ModelBinder, CollectionBinder){

    var BaseView = Backbone.View.extend({

        modelBinder: undefined,
        collectionBinder: undefined,

        constructor: function () {
            //var elManagerFactory = new Backbone.CollectionBinder.ElManagerFactory("", "");
            //this._collectionBinder = new Backbone.CollectionBinder(elManagerFactory);
            this.modelBinder = new Backbone.ModelBinder;
            Backbone.View.apply(this, arguments);
        },

        initialize: function () {

        },

        close: function () {
            this.modelBinder.unbind();
            //this.collectionBinder.unbind();
            this.off();
            this.undelegateEvents();
            if(this.childViews){
                this.childViews.close();
            }
            this.remove();
        }
    });

    return BaseView;

});
amakhrov commented 9 years ago

That's probably because the AMD version of CollectionBinder tries to load ModelBinder this way:

 define(['underscore', 'jquery', 'backbone', 'Backbone.ModelBinder'], factory);

The module name "Backbone.ModelBinder" doesn't match what you have in your requirejs config (modelbinder: 'libs/Backbone.ModelBinder',) - hence it fails to load the dependency.

amakhrov commented 9 years ago

BTW @theironcook, the CommonJS version of the factory doesn't load the 'ModelBinder' dependency, which looks like a bug.

khcoder commented 9 years ago

@amakhrov - Thanks very much! I had noticed the same code in the CollectionBinder late last night and experimented with changing the name, but just didn't try enough combinations. To capture the fix in case someone else comes along with the same question:

In the require.config statement, I changed: _modelbinder: 'libs/Backbone.ModelBinder',...to.... **'Backbone.ModelBinder': 'libs/Backbone.ModelBinder',**_

Then where 'define' is used for RequireJS within the views or elsewhere, I changed: _'modelbinder'.....to..... **'Backbone.ModelBinder'**_