4

I'm rewriting a category tree view into a RequireJS and Backbone app.

The structure is simple: each category contains a collection of child categories.

However, the circular dependency problem becomes quickly apparent. The category model requires the category collection and the category collection requires the category model.

There is quick blurb about circular dependency in the RequireJS docs:

http://requirejs.org/docs/api.html#circular

However, it seems that I'm missing something because I'm still getting undefineds and/or errors. I think just seeing 'b' and not 'a' in the examples is keeping me from understanding.

Is anyone able to provide a simple example that might clarify? That, or a better way of structuring this that wouldn't require a circular dependency.

Just a guy
  • 5,812
  • 4
  • 21
  • 25
  • What for do you need the circular dependency? As written in the require.js docs: "Circular dependencies are rare, and usually a sign that you might want to rethink the design". – SunnyRed Jan 25 '12 at 20:49
  • Yes, this is true. However, I outlined the structure above. If you can provide a tree structure that is not a recursive/circular dependency, please provide that example. – Just a guy Jan 25 '12 at 22:29
  • Sry, I didn't grasp your design correctly at first sight. So a) is using sth. like category and sub-category out of the question? b) Do you have seen these: http://stackoverflow.com/questions/6150378/backbone-with-a-tree-view-widget & http://stackoverflow.com/questions/6026752/backbone-collections-representing-tree-data. c) I think it could help, if you add your current code to clarify the issue. – SunnyRed Jan 26 '12 at 00:35
  • Thanks for the listing of those questions. Those are a bit different from this situation, but still good info. I think I've actually found the problem. I'm "in the zone" at the moment trying to hit a deadline. I'll post my solution in the next day or two (once the heat gets lifted a bit). – Just a guy Jan 27 '12 at 03:37

1 Answers1

2

Due to the circular reference, when require.js is loading "b" as a prerequisite for "a", it can't return a value for "a" because a's initModule() has not been call yet. However, by the time b.somethingElse() is called, module "a" has been initialized and the require("a") call will return.

The following code shows what's inside both modules - the order in which they get loaded does not matter. I've changed it from the require.js example a little to make it more obvious.

// Inside a.js:
define(["require", "b"],
    function initModule(require) {
        return {
            doSomehingWithA: function() { ...},
            doSomethingElse: function(title) {
                // by the time this function is called,
                // require("b") will properly resolve
                return require("b").doSomethingWithB();
            }
        }
    }
);

// Inside b.js:
define(["require", "a"],
    function initModule(require) {
        return {
            doSomethingWithB: function() {...},
            doSomethingElse: function(title) {
                // by the time this function is called,
                // require("a") will properly resolve
                return require("a").doSomethingWithA();
            }
        };
    }
);

BTW, while in general circular references are a symptom of bad design, that's not always so. For example, I've implemented a widget factory module which, among other things, referenced a "container widget" module which then had to reference the factory in order to create its content. Perfectly legit.

Stepan Riha
  • 1,736
  • 14
  • 12