32

I understand this is a very broad question, but I have worked with various aspects of this problem individually and am struggling to bring all the concepts and technologies together.

I'd like to specify that answers should include these technologies:

  • C#
  • MVC 3 w/ Razor
  • Javascript w/jQuery

Anything above and beyond those (such as Backbone.js, Entity Framework, etc) are welcome as suggestions if they help answer the question which is:

Using the above listed technologies, what is an optimal strategy for organizing code and logic while maintaining scalability and the ability to create a rich, fast, clean UI?

Ideally the focus should be put on a solution being deployed in a business/corporate environment. On that note, the technologies list above will not be changed so please don't offer solutions with "you should be using xxx instead of yyy that you are using now".

Background

I work with jQuery everyday, have adopted ASP.NET's MVC and have been working with C# for a long time. So you can present solutions assuming intermediate-to-advanced knowledge of those technologies.

I'll organize the question into smaller parts to make it simpler to respond to:

1. Project structure

Given I am working with ASP.NET MVC (in Visual Studio 2010) I would like a directory structure solution that offers some acceptance of the main layout this type of application. Something like Brunch I suppose, but with a little more detail of what each folder would contain and how it works with other areas of the app.

2. Data access

I'd like to modularize my data access as much as I can, with an API-type structure. You can assume lots of POCO objects (User, UserGroup, Customer, OrderHeader, OrderDetails, etc), but there will also be some complex reports that require data intensive SQL and careful UI rendering. EF + LINQ are fantastic for the former but not so much for the latter. I can't find something that seems to fit both scenarios without being overly complicated or overly simple.

3. Client-Side Code Organization and UI Rendering

Like most developers first picking up jQuery, I fell into the trap of mashing together code wherever it needed to go but quickly found it piling up and turning ugly. Although I've come leaps and bounds since then, I still struggle with modularizing my code and working with various parts of the UI without repeating code.

As an example, a typical piece of code I might write would look like this, I have commented the stuff that bothers me (note that I've since changed to using deferred AJAX calls and separated the actual data requests from the DOM manipulation):

$('#doSomethingDangerous').click(function () {
    // maybe confirm something first
    if (confirm('Are you sure you want to do this?')) {   

        // show a spinner?  something global would be preferred so I don't have to repeat this on every page 
        $('#loading').show();  

        // maybe the page should notify the user of what's going on in addition to the dialog?
        $('#results').show().html('<h2>Please wait, this may take a while...</h2>');  

        $.ajax({
            url: 'blah/DoDangerousThing',
            success: function (data) {                     
                // The results will be loaded to the DOM obviously, is there a better way to pull this type of specific code out of the data access calls?
                $('#results').empty();
                $('#results').append('<b>' + data.length + '</b> users were affected by this dangerous activity');
                $('#results').append('<ul>');

                // I've recently started to use jQuery templates for this sort of logic, is that the way to go?
                $(data).each(function (i, user) {
                    $('#results').append('<li>' + user.Username + '</li>');
                });                    
                $('#results').append('</ul>');

                // Need to hide the spinner, again would prefer to have this done elsewhere
                $('#loading').hide();
            }
        });
    }
});

General Questions

  • Client MVC vs. server MVC? My project is already a server-side MVC structure, so is there still a need for client MVC like Backbone.js provides?
  • Should Javascript files get created for each object (like an OrderHeader.js) and then minified/merged during the build? Or should there just be an Order.js which has logic for OrderHeader, OrderDetails, Reports etc?
  • How should complex queries be handled? Right now my leading theory is /Reports/Orders-By-Date/ or something along those lines and I use a custom SQL query that renders a custom dataset (or ViewModel) to the Razor View. But what about paging, sorting, etc? Is this better to be done client or server side? (assume larger dataset - 2 to 3 second SQL query)
  • I've read through Microsoft's Project Silk. Is this a good way to go? How does it compare to Backbone.js or others?
  • I'm very accustomed to an N-tiered architecture, do these concepts somewhat throw that out the window? It seems MVC is like a bunch of mini N-tiered sections within what would have been the front-end or top tier in the past.

Again the more specific your answers are the better they will be. I've read a lot of high level documentation and examples, I'm trying to better understand translating it into real world examples.

13
  • 2
    You put a lot of effort into this question, but it just doesn't seem like a Stackoverflow question to me. Perhaps the programmers stackexchange would be a better fit.
    – Pointy
    Commented Dec 13, 2011 at 22:55
  • 3
    I don't disagree that it's an interesting topic, but Stackoverflow is supposed to be about objective questions. Something like this question is basically the poster child for questions that will "likely solicit opinion, debate, arguments, polling, or extended discussion."
    – Pointy
    Commented Dec 14, 2011 at 0:00
  • 8
    There is a camp of folks who plan for the biggest scale all the time while I quietly take away their business because they took too long planning for something that never happened. Commented Dec 21, 2011 at 16:49
  • 1
    I agree with @Pointy that this belongs on the Programmers stack. Your question is very interesting, and I will folow it because I'm always looking for advice. But it is not an objective question, and is only going end up in preferential debates. As always, do what works best for your situation... none of us know anything about your network structure, number of clients or traffic stats, or build process... so the question is WAY too vague... all I know is avoid Silk. ;) Commented Dec 21, 2011 at 23:20
  • 1
    This question fits the very definition of "overly broad" and therefore "not a real question". If anything, the individual questions should be asked as individual questions with some slight background (too much and people will flag it "not a real question"). However, be careful, a number of the individual questions you are asking would probably be flagged as "not constructive" on their own, so I'd be careful about how you ask those questions.
    – casperOne
    Commented Dec 22, 2011 at 5:06

5 Answers 5

10

TerryR my friend, you and I should have a drink. We have some similar problems.

1. Project Structure: I agree with Eduardo that the folder structure in an MVC app leaves something to be desired. You have your standard Controllers, Models, and Views folders. But then the Views folder gets broken down into a different folder for each Controller, plus a Shared folder. And each Views/ControllerName or Views/Shared can be broken down into EditorTemplates and DisplayTemplates. But it lets you decide how to organize your Models folder (you can do with or without subfolders & additional namespace declarations).

God forbid you are using Areas, which duplicate the Controllers, Models, and Views folder structure for each area.

/Areas
    /Area1Name
        /Controllers
            FirstController.cs
            SecondController.cs
            ThirdController.cs
        /Models
            (can organize all in here or in separate folders / namespaces)
        /Views
            /First
                /DisplayTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                /EditorTemplates
                    WidgetAbc.cshtml <-- to be used by views in Views/First
                PartialViewAbc.cshtml <-- to be used by FirstController
            /Second
                PartialViewDef.cshtml <-- to be used by SecondController
            /Third
                PartialViewMno.cshtml <-- to be used by ThirdController
            /Shared
                /DisplayTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                /EditorTemplates
                    WidgetXyz.cshtml <-- to be used by any view in Area1
                PartialViewXyz.cshtml <-- to be used anywhere in Area1
            _ViewStart.cshtml <-- area needs its own _ViewStart.cshtml
            Web.config <-- put custom HTML Helper namespaces in here
        Area1NameRegistration.cs <-- define routes for area1 here
    /Area2Name
        /Controllers
        /Models
        /Views
        Area2NameRegistration.cs <-- define routes for area2 here

/Controllers
    AccountController.cs
    HomeController.cs
/Models
/Views
    /Account
        /DisplayTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        /EditorTemplates
            WidgetGhi.cshtml <-- to be used views in Views/Account
        PartialViewGhi.cshtml <-- to be used by AccountController
    /Home
        (same pattern as Account, views & templates are controller-specific)
    /Shared
        /DisplayTemplates 
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        /EditorTemplates
            EmailAddress.cshtml <-- to be used by any view in any area
            Time.cshtml <-- to be used by any view in any area
            Url.cshtml <-- to be used by any view in any area
        _Layout.cshtml <-- master layout page with sections
        Error.cshtml <-- custom page to show if unhandled exception occurs
    _ViewStart.cshtml <-- won't be used automatically in an area
    Web.config <-- put custom HTML Helper namespaces in here

This means if you are working with something like a WidgetController, you have to look in other folders to find the related WidgetViewModels, WidgetViews, WidgetEditorTemplates, WidgetDisplayTemplates, etc. As cumbersome as this may be, I stick to it and don't deviate from these MVC conventions. As far as putting a model, controller, and view in the same folder but with different namespaces, I avoid this because I use ReSharper. It will squiggly underline a namespace that doesn't match the folder where the class is located. I know I could turn this R# feature off, but it helps in other parts of the project.

For non-class files, MVC gives you Content and Scripts out of the box. We try to keep all of our static / non-compiled files in these places, again, to follow convention. Any time we incorporate a js library that uses themes (images and or css), the theme files all go somewhere under /content. For script, we just put all of them directly into /scripts. Originally this was to get JS intellisense from VS, but now that we get JS intellisense from R# regardless of placement in /scripts, I suppose we could deviate from that and divide scripts by folder to better organize. Are you using ReSharper? It is pure gold IMO.

Another little piece of gold that helps a lot with refactoring is T4MVC. Using this, we don't need to type in string paths for area names, controller names, action names, even files in content & scripts. T4MVC strongly types all of the magic strings for you. Here's a small sample of how your project structure doesn't matter as much if you're using T4MVC:

// no more magic strings in route definitions
context.MapRoutes(null,
    new[] { string.Empty, "features", "features/{version}" },
    new
    {
        area = MVC.PreviewArea.Name,
        controller = MVC.PreviewArea.Features.Name,
        action = MVC.PreviewArea.Features.ActionNames.ForPreview,
        version = "december-2011-preview-1",
    },
    new { httpMethod = new HttpMethodConstraint("GET") }
);

@* T4MVC renders .min.js script versions when project is targeted for release *@
<link href="@Url.Content(Links.content.Site_css)?r=201112B" rel="stylesheet" />
<script src="@Url.Content(Links.scripts.jquery_1_7_1_js)" type="text/javascript">
</script>

@* render a route URL as if you were calling an action method directly *@
<a href="@Url.Action(MVC.MyAreaName.MyControllerName.MyActionName
    (Model.SomeId))">@Html.DisplayFor(m => m.SomeText)</a>

// call action redirects as if you were executing an action method
return RedirectToAction(MVC.Area.MyController.DoSomething(obj1.Prop, null));

2. Data access: I have no experience with PetaPoco, but I'm sure it's worth checking out. For your complex reports, have you considered SQL Server Reporting services? Or, are you running on a different db? Sorry I'm not clear on what exactly you are asking for. We use EF + LINQ, but we also put certain knowledge about how to generate reports in domain classes. Thus, we have controller call domain service call repository, instead of having controller call repository directly. For ad-hoc reports we use SQL Reporting Services, which again isn't perfect, but our users like to be able to bring data into Excel easily, and SSRS makes that easy on us.

3. Client-Side Code Organization and UI Rendering: This is where I think I may be able to offer some help. Take a page from the book of MVC unobtrusive validation and unobtrusive AJAX. Consider this:

<img id="loading_spinner" src="/path/to/img" style="display:none;" />
<h2 id="loading_results" style="display:none;">
    Please wait, this may take a while...
</h2>
<div id="results">
</div>
<input id="doSomethingDangerous" class="u-std-ajax" 
    type="button" value="I'm feeling lucky" 
    data-myapp-confirm="Are you sure you want to do this?"
    data-myapp-show="loading_spinner,loading_results" 
    data-myapp-href="blah/DoDangerousThing" />

Ignore the ajax success function for now (more on this later). You can get away with a single script for some of your actions:

$('.u-std-ajax').click(function () {
    // maybe confirm something first
    var clicked = this;
    var confirmMessage = $(clicked).data('myapp-confirm');
    if (confirmMessage && !confirm(confirmMessage )) { return; } 

    // show a spinner?  something global would be preferred so 
    // I dont have to repeat this on every page 
    // maybe the page should notify the user of what's going on 
    // in addition to the dialog?
    var show = $(clicked).data('myapp-show');
    if (show) {
        var i, showIds = show.split(',');
        for (i = 0; i < showIds.length; i++) {
            $('#' + showIds[i]).show();
        }
    }

    var url = $(clicked).data('myapp-href');
    if (url) {
        $.ajax({
            url: url,
            complete: function () {                     
                // Need to hide the spinner, again would prefer to 
                // have this done elsewhere
                if (show) {
                    for (i = 0; i < showIds.length; i++) {
                        $('#' + showIds[i]).hide();
                    }
                }
            }
        });
    }
});

The above code will take care of the confirmation, showing the spinner, showing the wait message, and hiding the spinner / wait message after the ajax call is complete. You configure the behaviors using data-* attributes, like the unobtrusive libraries.

General Questions

- Client MVC vs. server MVC? I didn't try to librarify the actions you took in the success function because it looks like your controller is returning JSON. If your controllers are returning JSON, you might want to look at KnockoutJS. Knockout JS version 2.0 was released today. It can plug right into your JSON, so that an observable click can automatically bind data to your javascript templates. On the other hand if you don't mind having your ajax action methods return HTML instead of JSON, they can return the already-constructed UL with its LI children, and you can append that to an element by using data-myapp-response="results". Your success function would then just look like this:

success: function(html) {
    var responseId = $(clicked).data('myapp-response');
    if (responseId) {
        $('#' + responseId).empty().html(html);
    }
}

To sum up my best answer for this, if you must return JSON from your action methods, you are skipping the server-side View, so this really isn't server MVC -- it's just MC. If you return PartialViewResult with html to ajax calls, this is server MVC. So if your app must return JSON data for ajax calls, use client MVVM like KnockoutJS.

Either way, I don't like the JS you posted because it mixes your layout (html tags) with behavior (asynchronous data load). Choosing either server MVC with partial html views or client MVVM with pure JSON viewmodel data will solve this problem for you, but manually constructing DOM/HTML in javascript violates separation of concerns.

- Javascript file creation Apparently minification features are coming in .NET 4.5. If you go the unobtrusive route, there shouldn't be anything stopping you from loading all of your JS in 1 script file. I would be careful about creating different JS files for each entity type, you will end up with JS file explosion. Remember, once your script file is loaded, the browser should cache it for future requests.

- Complex queries I don't consider having feature like pagination, sorting, etc, as being complex. My preference is to handle this with URL's and server-side logic, to make the db queries as limited as needed. However we are deployed to Azure, so query optimization is important to us. For example: /widgets/show-{pageSize}-per-page/page-{pageNumber}/sort-by-{sortColumn}-{sortDirection}/{keyword}. EF and LINQ to Entities can handle pagination and sorting with methods like .Take(), .Skip(), .OrderBy(), and .OrderByDescending(), so you get what you need during the db trip. I haven't found the need for a clientlib yet, so I honestly don't know much about them. Look to other answers for more advice on that.

- Project silk Never heard of this one, will have to check it out. I am a big fan of Steve Sanderson, his books, his BeginCollectionItem HtmlHelper, and his blog. That said, I don't have any experience with KnockoutJS in production. I have checked out its tutorials, but I try not to commit to something until it's at least version 2.0. Like I mentioned, KnockoutJS 2.0 was just released.

- N-tier If by tier you mean different physical machine, then no, I don't think anything goes out any windows. Generally 3-tier means you have 3 machines. So you might have a fat client as your presentation tier, that runs on a user's machine. The fat client might access a service tier, that runs on an application server and returns XML or whatever to the fat client. And the service tier might get its data from a SQL server on a 3rd machine.

MVC is one layer, on 1 tier. Your controllers, models, and views are all part of your Presentation Layer, which is 1 tier in the physical architecture. MVC implements the Model-View-Controller pattern, which is where you might be seeing additional layers. However, try not to think of these 3 aspects as tiers or layers. Try to think of all 3 of them as Presentation Layer Concerns.

Update after pres/bus/data comment

Okay, so you are using tier and layer interchangably. I usually use the term "layer" for logical / project / assembly divisions, and tier for physical network separation. Sorry for the confusion.

You will find quite a few people in the MVC camp who say you should not use the "Models" in MVC for your entity data model, nor should you use your Controllers for business logic. Ideally your models should be view-specific ViewModels. Using something like Automapper, you take your entities from your domain model and DTO them into ViewModels, sculpted specifically for use by the view.

Any business rules should also be part of your domain, and you can implement them using domain services / factory pattern / whatever is appropriate in your domain layer, not in the MVC presentation layer. Controllers should be dumb, though not quite as dumb as models, and should give responsibility to the domain for anything that requires business knowledge. Controllers manage the flow of HTTP requests and responses, but anything with real business value should be above the controller's pay grade.

So, you can still have a layered architecture, with MVC as the presentation layer. It is a client of your application layer, service layer, or domain layer, depending on how you architect it. But ultimately your entity model should be part of the domain, not models in MVC.

5
  • I totally agree with this answer! Especially: • Resharper is an MVC genius ... from error checking to IDE navigation, its usefulness blows me away! • Server-Side MVC is almost always the best approach • MVC is not 3 separate tiers, it is a single Presentation Layer - I never really thought about it this way, but it is absolutely correct. Commented Dec 21, 2011 at 23:55
  • Very nice answer, definitely what I was looking for at the cost of my 300 rep. Drinks are on me if you're in the Toronto area :)
    – TerryR
    Commented Dec 22, 2011 at 0:40
  • btw I always considered N-tier as Pres/Bus/Data regardless of where they physically sat. That's why I said MVC almost removes that architecture because it basically combines the 3, what you said somewhat agrees with that but also gives a different perspective on it.
    – TerryR
    Commented Dec 22, 2011 at 0:48
  • I would warn against the ViewModel, model-per-view, approach. I recently ran into situation where I'd wished later that I did not have this abstraction from DTO to ViewModel. See: stackoverflow.com/q/7181980/109456
    – mklinker
    Commented Dec 22, 2011 at 4:26
  • As a general rule, I don't like to see the jQuery and instead write objects with interfaces that any server-side dev would be able to understand pretty quickly with JQ or the DOM API doing the business inside. I also really like Django's URLConfig concept and have found it helpful for setting up objects for implementation on pages. I have no idea what the MV? libraries are supposed to do for me though. They're not a perfect fit for the problem, IMO and the DOM + event delegation is all the model I need for handling pages without being excessively tied to specific structure. Commented Jun 13, 2013 at 5:10
6

I'm not going to write a full answer, but want to share some tips.

My tips:

1. Project structure
I've found that the default MVC structure is not good for me. I generally work in the controller, views and model of the same entity (think product, order, customer) at the same time. So, I like to have the files in the same folder, but with different namespaces.

2. Data
If you go with Linq-to-SQL or EF you will regret later.
I use PetaPoco that allows me to run SQL retrieving and updating records without the mapping pain, but without learning a new way to do things and without the performance nightmares.

I have a code generator for creating the initial POCO class with the PetaPoco attributes, and then change the class when some field is added or removed.

PetaPoco works with dynamic and standard classes, so you don't have any compromises (Massive is all dynamic and Dapper all standard classes)

I also generate a master SQL, using the built in SqlBuilder, that contains all the standard joins for the entity, but no WHERE's so I reuse the same SQL for retrieving one entity or a list.

3. Jquery You can standarize some parts of the UI using a general jQuery call (stuffing some data inside the HTML element).

For example, I have this for deleting.

var deleteLinkObj;
// delete Link
$('.jbtn-borrar').click(function () {
    deleteLinkObj = $(this);  //for future use
    $('#delete-dialog').dialog('open');
    return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
    autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
    buttons: {
        "Borrar": function () {
            $.post(deleteLinkObj[0].href, function (data) {  //Post to action
                if (data == 'OK') {
                    deleteLinkObj.closest("tr").hide('fast'); //Hide Row
                }
                else {
                    alert(data);
                }
            });
            $(this).dialog("close");
        },
        "Cancelar": function () {
            $(this).dialog("close");
        }
    }
});

I just need to add the class jbtn-borrar to a hyperlink, and it shows a dialog, delete the record and hide the tr

But don't overthink it. Your app will shine with the small touches in every view.

Client MVC vs. server MVC
Server MVC. Take advantage of partial views that you can use in initial rendering and refresh some parts with Ajax using the same view. See this excellent article

How should complex queries be handled (lets call it a Report)
I use a class that have the Report parameters as properties (handy for using MVC automapping) and a Generate method that executes the query and fill a List of a custom class (if you don't have a class that fit the ViewModel)
You can use this class as the model of the view and fill the table with the generated list.

Microsoft's Project Silk
Overarchitected. Run as fast as you can in the opposite direction.

1
  • Funny, as I read through Project Silk I kept getting this nagging feeling and I couldn't place it. Overarchitected might have been that...
    – TerryR
    Commented Dec 14, 2011 at 18:21
3

1. Project structure

I have 2 project files in my solution

1) Service/Business layer I place all my Business logic and DB access code and POCOs into this separate project. No need for a Data Access layer if you using a ORM as the ORM already abstracts the DB layer.

2) UI layer contains all my Views, Controllers, Models, Scripts, CSS

I try to make my controllers, Views, scripts and CSS all use a similar folder structure. Also structure my files to match the URL path as much as possible. To avoid having to write custom routing.

Use the DisplayTemplates, EditorTemplates, Partial views and the Shared folder as much as possible.

I then structure all my Scripts to match the same Areas, Controllers of my c# files So I would have a common.js file at the root a js file per page and a common.js file for each area.

CSS files I normally have 2 + n (where n is the number of areas) 1st CSS file is CSS just for the landing page only to help with a quicker page load time (probably not so important for business/corporate environment) 2nd CSS file is a common.css which has all the styles for all the other pages. Then another common.css file for each area for example a AdminArea.css file which has CSS for every admin page.

2. Data access

If I use Entity Framework I use CodeFirst as it works very well with POCOS and you do not have a model to maintain. nHibernate is much more powerful but has a steper learning curve. For Paging of DB results I have a reuseable util c# class and patial view I use for all my views.

For complex queries and generating reports I use Stored procedures. They are much easier to write and maintain and offer more power the LINQ. They can also be reused by other services like SSRS. I use automapper to convert the dataset returned to back to the same POCOs entiry framework uses.

3. Client-Side Code Organization and UI Rendering

Eduardo Molteni answer has a good example code. Additionally I would definitely recommend using knockoutjs as it has both good templating and bindings. If you use JSON for all your AJAX calls which I use a lot of then having the UI auto map to the JS objects is a huge time saver.

General Questions

Complex queries should live in a stored proc. (see emeraldcode.com comment)

You still keep your N-tiered architecture using this MVC.

0
1

I've recently been moved to believe that, if you plan on using the three technologies you listed, you should first start by assuming the adoption of Orchard CMS. I believe it is the best single answer to your central requirement:

What is an optimal strategy for organizing code and logic while maintaining scalability and the ability to create a rich, fast, clean UI?

In the Ochard scenario, anything you can't address through its configuration mechanisms you would then handle either through the addition of free online modules, or writing your own module (which of course are C#, razor, etcetera). Code organization is a strength of Orchard.

As for data access, there are enough pros and cons to a full-bore ORM that I've also come to think that a micro-ORM is the best take. Try Massive or Dapper. Both were featured on Hanselminutes. I'll summarize the two by saying this: abstractions from SQL almost invariably break down as a project scales up. In the end, the best solution for DB access is this abstraction called SQL (bit of sarcasm, but true). Let the micro-ORM work with that, and you've got gold.

Put Orchard together with the micro-ORMs, and you can slice steel like butter. Er, meaning you can develop quickly, scale, and have code that is readily maintainable by a team that receives the hand-off.

0

Not sure how I missed this question but I'll add my two cents two years later.

Client MVC vs. server MVC? My project is already a server-side MVC structure, so is there still a need for client MVC like Backbone.js provides?

MVC and MV? even before it got pushed to the client-side has basically de-evolved into a marketing term that really only promises that somehow data will be separated from other stuff which is by and large a great idea but not really that hard to DIY. No matter what approach you're taking, just before or right in the middle of making changes to HTML that affects presentation or interaction possibilities is the absolute most awful place to be sorting out what the business wants you to do with the data.

There is nothing special about "view logic." The same principle should apply to all logic. And that is, don't do anything now that would have made a lot more sense to do before now. When all your ducks are in a row before you pass some data or initiate a new process, that previous phase is likely to be much more re-usable to anything else in the system doing something similar.

Should Javascript files get created for each object (like an OrderHeader.js) and then minified/merged during the build? Or should there just be an Order.js which has logic for OrderHeader, OrderDetails, Reports etc?

It's really up to you but I would try to get away from the one-file, one-class thing. I've never understood why it was helpful for instance have to find the abstract file and the interface, and the files implementing, etc... Categorize on broader concerns. ctrl+f ain't that hard to use if it goes a little long.

That said, you should never recombine JS to make files smaller on the web. Browsers cache JS so you're just forcing reloads of the same JavaScript by sticking old JS in new files. Barring staggering amounts of JavaScript, the only time you shouldn't have all the JS on the page is when a very large quantity of it that's highly specific to one section of the site with no overlap/gray areas will never be needed on a given page.

And FFS do not fuss with dependency management with JavaScript on the web. Require.js on medium to low complexity websites makes me want to club baby seals. Stick your third party libraries in a top block. Your in-house libraries in the second block. And then your implementation code (which should never be a tenth as long as your in-house library code - i.e. very succinct and clear and easy to understand ) in that third bock.

How should complex queries be handled? Right now my leading theory is /Reports/Orders-By-Date/ or something along those lines and I use a custom SQL query that renders a custom dataset (or ViewModel) to the Razor View. But what about paging, sorting, etc? Is this better to be done client or server side? (assume larger dataset - 2 to 3 second SQL query) I've read through Microsoft's Project Silk. Is this a good way to go? How does it compare to Backbone.js or others?

Honestly, I'd say whatever is easier for you that doesn't stink for the customer. Web pages load pretty damn fast on modern technology. If implementing in Ajax is a lot of pain for you, don't. Just go with what you know best and then you can get fancy later and see how you like it for paging. If you're building a new complex app from scratch, start with essential and hit neat-o later.

I'm very accustomed to an N-tiered architecture, do these concepts somewhat throw that out the window? It seems MVC is like a bunch of mini N-tiered sections within what would have been the front-end or top tier in the past.

It really depends on whoever's fantasy idea of what MV? is. IMO, the microcosm thing tends to work very well. A class of widget that separates data, communication, and view-related stuff internally works great. On the client-side web, the critical thing, IMO, is to maintain a balance of keeping concerns separated without needlessly fragmenting into tiny little concerns whose reassembly makes it difficult to understand and re-use and modify things. Basic "duh" OOP works great here. You don't want complex processes. You want obviously named things that can be moved around and told to do stuff. Here's a few tips on that front:

  • KISS that (OOP) interface I don't want to see DOM or jQuery or anything else a pinch-hitting server-side dev couldn't figure out fairly quickly in my implementation code. All that person should have to know is what class to slap on a div container and what switch to flip to make a fairly generic set of UI active on a given page. Variations on a theme should still be accomplished by passing in well-documented/commented options objects before they have to start looking at document.get<anything> or understand anything beyond the barest basics of CSS.

  • Okay so how do you do that? Well, we have already have a model. It's called the DOM. And we have event delegation. If you're not indiscriminately shutting down event bubbling (don't do that - it's there because it's useful) you can pick up every single even from the body if you want. Then examine the passed event object's target property and determine who just 'whatevered.' If you are structuring an HTML document sensibly there is no reason to not to use it as a delegating model. Behavior and content structure are naturally linked. It's okay for the two to have overlapping identifiers.

  • Don't Pay For Data-Binding And by "pay" I of course mean "slap a library onto your codebase that insists you do things just-so all the time in order to get some miracle benefit that's actually not hard to DIY." JQ's event system makes it pretty easy.

Example Time:

function PoliticianData(){ //a constructor

    var
        that = this, //I hate 'that' but example so convention

        flavorsOfLie = {

            lies: "Oh Prism? Psh... no we're all good. There's a guy keeping an eye on that.",

            damnedLies: "50% of the people chose to not give a damn when asked whether it was better to let the terrorists win or not give a damn."

        }
    ;//end instance vars

    this.updateLies = function( lieType, newData ){
        flavorsOfLie[lieType] = newData;
        $(that).trigger({type:'update', lieType:lieType, newData: newData });
    }

    //so everytime you use the updateLies method, we can have a listener respond
    //and pass the data
}

var filthyLies = new PoliticianData();

$(filthyLies).on('update', function(e){
    stickNewDataInHTMLWithSomeFuncDefinedElsewhere(e.lieType, e.newData);
} );

filthyLies.update('damnedLies','50% of the people said they didn\'t give a damn');
//oh look, WaPo's front page just changed!
  • Don't Hide the Web The chief source of suckery in all early attempts at making the client-side easy for server-side and app devs hinged on this critical point. HTTP Requests are not and never were complicated. They didn't require an 18 !@#$ing layer confusing-event-name-at-each-stage monstrosity in order to make it easier to understand. Likewise, there's a lot to know about the client-side but there's no reason to hide from the HTML and the DOM that interacts with it by slapping a big giant model on top of it. It already is a big giant model and it works very well. All we need to make it a bit more manageable is some sensible OOP practices and some JS and DOM knowledge.

  • Favor Flexibility

EXTjs <====flexibility scale====> jQuery (not necessarily any of its plug-ins)

IMO, tools that let you DIY rapidly are always the better choice. Tools that did it all for you are only the right choice when nobody over your head is being particularly picky about the details and you don't mind ceding control to the very thing that's supposed to be helping you. I've actually seen plug-ins that validate the HTML to make sure you don't sneak a different kind of element with all the same exact display traits in there. Why? I only have theories. I think it boils down to completists really hating the idea of somebody using their stuff in a way that wasn't intended and that's always inevitably what somebody wants you to do in UI.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.