javascriptjqueryasp.net-mvc-4angularjssinglepage

Very large single page application design problems


I am currently writing whats going to be a very, very large single page web/javascript application.

Technologies I am using are ASP.NET MVC4, jquery, knockout.js and amplify.js.

The problem I am having is that most if not all of the single page application examples are for smaller applications where having all of the script templates (be it jquery, handlbars, etc...) are all in the same file along with the rest of the html code. This is fine for smaller apps but the application I am building is an entire maintenance logistics application with many, many, many screens.

The approach I took so far is I have an outer shell (my main index.cshtml file) and I am using jquery's load() method to load or rather inject the particular file I need when a user makes a certain selection.

example:

function handleLoginClick(){

    App.mainContentContainer.delegate('#btnLogin', 'click', function() {

        App.loadModule('Home/ProductionControlMenu', App.MainMenuView.render());

    });

}

here's the code for the App.loadModule function:

App.loadModule = function(path, callback){

    App.mainContentContainer.load(App.siteRoot + path, callback);

};

All was going well until I needed to actually start interacting with the various form elements on the newly loaded screen. jquery can't seem to get a handle on them directly. I can't use .live() or .delegate() because they aren't events, they are textboxes and buttons and sometimes I need to change their css classes.

They only way I found is to get a handle on an element from the outer shell (something that wasn't loaded via .load() ) and use jquery's .find() method like so:

  App.mainContentContainer.find('#btnLogin').addClass('disabled');

clearly I don't want to have to do something like this everytime I need to interact with or even retrieve values from a form element.

Does anybody have any ideas as to how I can create a maintainable very large single page application with potentially hundreds of .html files without having to have all that html code located in a single file and still get around this .load() issue I am having?

Any thoughts would be greatly appreciated. :-)

V/R

Chris

UPDATE

I thought I'd post an update and as to how things went and what worked. After much research I decided to go with Google's AngularJS Javascript framework. It simplified the ordeal exponentially and I would definitely, definitely advise all who are looking into making a large SPA to give it a look.

Links:

Main Site http://angularjs.org/

Awesome free short videos on Angular: http://www.egghead.io/


Solution

  • This is actually a very complicated question as it really gets down to the design of your architecture.

    For large-scale single-page applications, it's best to use some sort of front-end MV* style framework such as backbone.js, which ties in to jQuery quite usefully. You should also think about using some sort of dependency management framework such as require.js in order to load your scripts and dependencies asynchronously, and even better -- use the AMD pattern in your application design to make your architecture modular and easier to manage.

    As far as how this relates to your MVC4 project, you have some options:

    1. Do you want to use MVC as a "service layer" of sorts, that simply returns JSON objects, allowing your front-end to do the markup/template creation (think handlebars.js), or
    2. Do you want your MVC project to return partial views (HTML) as a response, where you leverage the Razor templating system and simply use the front end to display what comes back from the server?

    Either way, you will have to devise a way to handle front-end events and navigation (backbone provides both of these things when coupled with jQuery). Even more complicated is the pattern you choose to notify one view of another view's activities (there are many ways to do this) -- a publish/subscribe pattern for example.

    I hope I have helped a bit, I know I'm not fully answering the question, but the answer could get really long!