views:

920

answers:

6

Before you answer, this question is complicated:

  1. We are developing in asp.net / asp.net mvc / jQuery but I'm open to solutions on any platform using any framework
  2. I think logic like sorting / hiding columns / re-arranging columns / validation (where it makes sense) should be on the client-side
  3. I think logic like searching / updating the db / running workflows should be on the server side (just because of security / debugging reasons)

What we are trying to do is NOT CREATE A MESS in our UI by writing a bunch of javascript to deal with the same feature in different contexts. I understand that I can use a javascript file + object oriented javascript, I'm looking for the pattern that makes it all easier.

One solution proposed was to have an MVC model on both the client and server side, where we can encapsulate javascript functionality in client side controllers, then use them in different parts of the site. However, this means that we have 2 MVC implementations!

Is this overkill? How would you expand on this solution? What other solutions are there?

+3  A: 

On two; you should always have server side validation as well as client side validation

On three; if you can find a way to manipulate the DB on the client side that would be impressive ;)

I don't know how ASP.net works though, so I am solely speaking from my PHP experience.

I would write controls that are paired by server and client code. Each control needs a form, client side logic and server side logic. The form is written out by your templating engine, the client side logic is attached to the form and written in JS and the server side logic is a controller/action pair somewhere that manipulates the model. Clearly, you would not want to couple your client side logic to a specific action/controller, so be sure to define an interface that can be used to talk to your control instead...

Then for each form I would write a class in javascript that instances your controls. For example; you may have a control:

{include file = "list_view.php" id = "ListView1" data = $Data.List}

which would print your form out. Then in your page controller class:

this.ListView1 = new ListViewController({id : "ListView1", serverCtrl : "Users"});

Now you can use "this.ListView1" to manipulate the list view. The list view controller does stuff like makes AJAX queries for new pages if the use presses the next page button - and also handles columns and sorting (which will also delegate to the server).

nlaq
I like the idea here- basically a keep it simple approach, the only thing I was trying to avoid was a lot of "wiring it up" where javascript methods on the control interface simply delegate to server side logic. However, it may just be something I can't avoid. Thanks!
Zachary Yates
A: 

... It depends...

Actually the best things is developing the UI using a css / javascript / html for a style / behaviour / structure + data, in these days people wants ajax interactions (they see that cooly things everywhere so they expectation is that they don't have to reload entire pages everytime) so I think you should take this into consideration. BTW MVC ends when your content is served, and it haven't to be HTML content, you can serve xml or json in your View.

ASP.NET MVC permit to return Content("TEXT") so you can organize your back end using MVC and user interaction/behaviour in javascript, for example when an ajax call is sent to the server you are calling the Controller part of your application, so you can call an Ajax action that switch to an ajax Model that render as JSON and return to the JS part of your UI (The behavioural part).

Since the Behavioural part is defined in your View part (initial View is composed of CSS / HTML JS) so as long as is a presentational part I think you haven't broken the MVC patterns.

PS. I' m was forgetting to say that obviously DB actions stay in your model (you can think at model as the place where the Data Access Layer + Business Object Layer stay)

kentaromiura
Perhaps I should have rephrased the question, my real problem is that MVC _does not_ end when my content is served, and I can't think of reason that it should. I'm trying to incorporate that AJAXY feel with a clean, structured code base that doesn't just delegate every action back to the server.
Zachary Yates
What I would mean is that in "classic" MVC the Action ends when content is served.Trying to duplicate the MVC pattern in the View, in my opinion, broke the MVC logic since you've 2 controllers, and this is not the best way to act, you're adding complexity and probably coupling with the views
kentaromiura
+3  A: 

I just googled this so take it with a grain of salt. JavascriptMVC claims to be a MVC framework. Again, I have no experience with it but it may be worth a look.

David Robbins
Thats a great link! I haven't played with it yet but it looks like something that would help.
Zachary Yates
+1  A: 

If you are using MVC, then I assume your view utilizes a template engine. Each page is associated with a template, and each template usually contains a reference to one or more scripts. The question is, how are your scripts referenced in the template? Are they static, or are they dynamic? Within your controllers, you should have the option to include any scripts in the view used for a page regardless of the template. I often suggest this "include it when needed" approach because simulating MVC client-side means exactly what you said it means -- you have two MVC frameworks now to maintain. Not only that -- with most client-side models they have direct access to your server-side model, which defeats the purpose of your server-side MVC. You're now bypassing the controller completely.

When it comes to JavaScript, the best thing to do is to keep it very simple. With jQuery, you have an even better chance of making this happen. Every page gets the core, and you have several other JavaScript files in the same folder, each one being a plugin or extension of the jQuery object that maps to very specific functionality. If developers want to know if functionality already exists, all you do is check the file system where the JavaScript files are located. If the plugin exists, include it in your controller for use in a page. This way you can build helpers on the server-side that sit between your client-side app and any existing controllers. The helper is specific to that functionality and plugin, and you do not open up blanket access to your models from the client-side.

hal10001
+2  A: 

Keep it simple. Build your application to be fully functional in the MVC ASP.Net framework. No JavaScript required at this stage of testing.

Now add the nice stuff by linking jQuery in your site.master (Google link) and at the bottom of your Views that require a web 2.0 experience, link to appropriate JS files that add the functionality unobtrusively. Switch off JS and your app degrades back to the previous step.

For example, you want to add client-side validation in addition to server-side. The JS file would attach an event handler to the forms onsubmit. The handler would then use an object that has been generated by the server (The same object used for server validation) which would be best as a JSON object because that's compatible with JS and ASP.NET. The members of the object would be the rules to check and error messages to write into the DOM at the same location you opted for the server-side errors. Your handler returning false until all is valid and true when correct.

You want a nice fancy feature, such as a lightbox view of your pictures. Add a plugin for your view, modify the markup <ul id="lightup"> ..., add the code:

$(function() {
   $(#lightup).showit(400); // or something like that
});

and your good to go.

Try to separate shared functionality from your server code into a web service or page so that both the client, through XHR and the server, can share the same functionality/data.

Great answer. Thanks for taking the time on an old question.
Zachary Yates
A: 

don't return json/xml to views and build them with jquery dom generation on the client. It's ok performance wise on decent machines, but I made this mistake and when trying to view the site with my iphone it takes 60 seconds to load...and I'm the only person on the site! :-)

so at this point I just use jquery dom injection for ajaxy updates and not rendering the entire page.

sam