9

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/

cpeele00
  • 883
  • 4
  • 14
  • 29

8 Answers8

12

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!

Bryan A
  • 3,598
  • 1
  • 23
  • 29
  • 1
    Plan b, thanks for your help man. I'm thinking I may go with rendering partials and then use jquery templates or some other kind like it on the partials for rendering the json data coming back from the Web API. I'll use Require.js and Knockout for the javascript. How's that sound? – cpeele00 Dec 06 '12 at 03:20
  • I think that's a very reasonable approach! Whatever you do, if this is an "enterprisey" style app that you plan on coming back to, just keep it consistent so you don't drive yourself nuts! That's the hardest part when you you design an app like this. – Bryan A Dec 06 '12 at 15:36
  • 1
    @cpeele00 If your going the render partial route I would just use [**PJAX**](https://github.com/defunkt/jquery-pjax) or DJAX then you just develop your app Web 1.0. See my [answer](http://stackoverflow.com/a/13750279/318174). – Adam Gent Dec 06 '12 at 18:35
7

Lots of things are wrong with your approach. What I'd recommend is to watch some presentations on how people build Single Page Applications and what tooling is mostly used.

This seems like something reasonable: http://singlepageappbook.com/

You will at least want

  • some kind of modules system (I recommend AMD – http://requirejs.org)
  • an MV* framework (Backbone, Ember.js etc.)
  • DOM/AJAX Framework (jQuery, Mootools etc.). Some frameworks offer this and all of the above (Dojo, YUI, Sencha)
  • build solution (to have different environment in development / production)

Couple of good links:

  1. http://nerds.airbnb.com/slides-and-video-from-spike-brehms-tech-talk
  2. http://video.copenhagenjs.dk/video/3413395/simon-hjberg-swipely-building
  3. http://backstage.soundcloud.com/2012/06/building-the-next-soundcloud/
  4. http://www.youtube.com/watch?v=vXjVFPosQHw
Misha Reyzlin
  • 13,736
  • 4
  • 54
  • 63
  • thanks for info. Those are all things I am planning on using however doesn't my initial problem remain the same: simply too much html to stuff into templates to put on a single page. The size of the page would be huge. I understand about using AMD, require.js for js but I need to solve the problem with handling tons of html via too many templates. Unless I'm missing something? – cpeele00 Dec 05 '12 at 19:17
  • You can load templates with requirejs via its text plugin. However, most templates, when pre-compiled, actually are JS files (if you are using proper and fast technology over simple HTML partials then modified via DOM API). – Misha Reyzlin Dec 05 '12 at 19:23
  • very simplified: if your template is `
  • {{username}}
  • ` then after you compile it it will become `function (username) { return "
  • " + username + "
  • "; }`. Now when you call your template's engine `render` method, it will take this JS function and call it with appropriate parameters. This is faster and more flexible than using HTML as templates. – Misha Reyzlin Dec 05 '12 at 19:26