Coder Social home page Coder Social logo

Comments (7)

geekdave avatar geekdave commented on July 21, 2024

Liam, could you try changing:

MyApp.Routers.Books = new MyApp.Books.Router("books/");

to...

MyApp.Routers.Books = true;
new MyApp.Books.Router("books/");

We really don't need to store a reference to the subrouter in the MyApp namespace. This is just a check to see if it's already been initialized.

Trying this out would test your theory. I don't have access to an IE8 instance at the moment, so I can't test this myself.

from backbone.subroute.

carpeliam avatar carpeliam commented on July 21, 2024

What that does is calls invokeBooksModule, then creates the books router, then calls invokesBooksModule again, but never invokes the searchBooks function within the books module.

So what that makes me think is that, for some reason, those subroutes aren't getting registered properly? Or, if multiple routes match (which seems to be the case), it's not picking the one we want.

from backbone.subroute.

geekdave avatar geekdave commented on July 21, 2024

I think I see what's going on here. When we initialize a SubRouter from inside a base router, in response to a route, we have to be sure that this logic only gets called once. Otherwise, the initial navigation event from the SubRouter's initialize() call will result in the base route being called again, and we get a stack overflow.

Here's how I solve it in my application code. This is probably a good candidate for a general solution at the plugin level.

In my main router, I have a route set up like this, which is intended to "bootstrap" a new subroute by taking the subroute name as the appName parameter, and the rest of the route as the *navPath splat.

"app/:appName/*navPath":"loadApp"

My route callback function looks like this:

loadApp:function ( appName, navPath ) {

    this.subRouters = this.subRouters || {};

    // check if we've already loaded this module.  if so, there
    // is no need to reload it.  the submodule's subroutes will
    // handle the URL without us doing anything here.                
    if ( !this.subRouters[appName] ) {

        this.subRouters[appName] = true;

        // load the app module asychronously
        require( [appName + "/src/AppRouter"], function ( appClass ) {

            var appRouter = new appClass( 
                "app/" + appName, 
                {
                    createTrailingSlashRoutes: true,
                    appName:appName
                } 
            );

        } );
    }
}

The idea is to only initialize a named SubRouter once, and then after that whenever the route matches an already-initialized sub-route, it's a no-op. Since the sub-route is already initialized, it will respond without the base router needing to do anything else.

Perhaps backbone-subroute.js can maintain its own internal list of named subroutes, and handle this no-op logic itself? I'm not sure if this pattern fits for everyone, but I'm open to giving it a shot.

Can you please test this using the latest v0.2 code, and the above pattern to see if it resolves the issue?

from backbone.subroute.

patrixd avatar patrixd commented on July 21, 2024

Thank you! I tried with the latest v0.2 code and it works perfectly on ie8 ^^ (I never had problems with ie9)

from backbone.subroute.

geekdave avatar geekdave commented on July 21, 2024

@carpeliam : I'm going to close this issue based on patrixd's comment. Please let me know if your original issue is solved (using the code snippet above which checks for existing subroutes before re-instantiating them) and reopen the issue if it's still reproducible. Thanks to everyone for your feedback.

from backbone.subroute.

kalebdf avatar kalebdf commented on July 21, 2024

@geekdave Does this work with r.js optimized code? Is the thought to define and require all modules (with Routers) that we expect?

There is definitely an error case here when the user visits http://myapp.com/crazyurlthatdoesntmakesense which of course has no router.

from backbone.subroute.

geekdave avatar geekdave commented on July 21, 2024

@kalebdf I'm definitely mixing in some code that's very specific to my own use cases here. In my case, we do run the r.js optimizer, and we create one module for the "base" framework/shell, and individual modules for each sub-application, which is each represented by a sub-router.

This is why we do the inline require() call, which means that each sub-route is lazy-loaded based on the URL, with no need to pre-define any module-specific sub-routes up-front. We simply create that generic splat. As you noticed, we are not handling the error case where the user manually types in some random URL. So we still need a solution for that.

The point I was trying to illustrate was more simple, however. Whether you use my generic splat solution, or whether you manually define all of your subroute paths up-front, the important thing is to have a guard to make sure you are not re-initializing a subroute more than once. Otherwise, this stack overflow issue occurs.

I'm considering baking this support directly into the plugin, to first check (using some kind of Singleton pattern) if we already have a registered subroute for a given prefix, and if so, we just no-op it. I'm open to thoughts on this, but it seems like many people might be hitting the same issue with the overflow and it would be great if everyone didn't have to use the same boilerplate code to work around it.

from backbone.subroute.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.