• 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Ajax and MVC

#1
[eluser]JosGo[/eluser]
You are on a CI-screen, hit a button and through a url and posting some variables you get at a controller which uses a model and a view. A new CI-screen is built with probably the same menu and a different content. That's how mvc using CI appears to me. Schematic it's like in the attached file mvc2.png. At least that's how I see things.

When you're using Ajax you do not want an entirely new screen. You just want a part of the screen replaced by a new list of data or new details or whatever. I would like it if I could make an Ajax-call, then dependending on the Ajax-call, start a specific controller, use a model (possibly) and after that use a view. But this view should not send it's output to the user's browser but to a specified DIV. I tried to schematize this in the attached file ajaxmvc2.png. This seems the correct way to me, as it makes it possible to create an entirely Ajax-driven application and still use the MVC-approach. I took quite some time but I have still not found a way to do this. Anybody having ideas? Are extensions needed to do this? Is this not what we should want with CI? Does CI have to be rewritten for this methodology?

#2
[eluser]kucerar[/eluser]
Makes sense to me :-)...hadn't thought about it that simply. The boilerplate ajax targets the specified DIV innerHTML with the output from the view. I guess a DOM helper would be OK to use for the ajax piece (jquery?). Nice diagram BTW.

#3
[eluser]esra[/eluser]
Take a look at Coolfactor's View library:

http://ellislab.com/forums/viewthread/49910/

This will allow you to use a master view (PHP template) to handle the physical structure of your pages and each page (master view) could be composed of numerous partial views--some visible and some hidden. Some of the logic for loading and switching between partial views can remain in your controllers.

I'm working on something similar using a combination of EXT widgets and JQuery. Each set of partial views managed by your controller could have an associated Javascript and CSS file, as well as your master templates.

You can experiment with this using the sample layout examples included with EXT. Just disassemble them into a master view and collection of partial views. Then reassemble them using Coolfactor's View library. Get the master views and partial views working to your satisfaction using the views and javascript, then write helpers to use in your views to wrap your javascript functions in PHP.

The JQuery.php library on the wiki is a special version written for CodeIgniter. At least one other JQuery wrapper for PHP has been released in recent weeks. At this point, I have not used either JQuery wrapper (just Javascript).

#4
[eluser]Michael Ekoka[/eluser]
Hi JosGo, I am not aware of any universally accepted methodology to integrate Ajax into MVC, but I think you're on the right path. It is an interesting thread that you're opening, I wish more people would share their view on the matter. Personally, from what I have learned about Ajax application development, I think there are currently 2 or 3 approaches that are often used in projects:

The first one is to consider the application being developed as a desktop application running in a browser (e.g. zimbra), so Javascript and Ajax are an inherent part of the whole. If you don't have them enabled, it is accepted that you won't run the application. The browser is only used as a convenience, not as a way to make things universally accessible. This approach simplifies development a lot and integrates well into MVC, as virtually any request made to the server uses ajax. Your application will usually load one main layout on the first request, and from then on your controllers will only return very specific view fragments for each action.

The second approach, which is actually the first one with an addition, consists of splitting development of the same application in 2 projects. One with ajax and one without (e.g. gmail). The separate teams will work well on their own, but what becomes difficult about this is to keep the 2 projects in synch. For a company with a treasure chest like google, this is trivial.

The last one that I am familiar with and which is what I would adopt if/when I'll decide to "ajaxify" my application, is known as "Progressive Enhancement". It promotes incremental, unobtrusive javascript/ajax additions to already existing basic PHP/HTML actions. The principle behind that method of development is to use javascript, if enabled, to "hijack" normal hyperlinks, and replace their actions with some ajax counterparts. If js is not enabled the action proceeds as originally intended in pure HTML. One of the major benefits of this approach is graceful degradation. Your application should work normally with or without js enabled. If you use this approach you usually start as a normal PHP/HTML app, but you always plan for a later ajax integration. For this, one technique consists of forking your controller's action at the point where it loads a view.

Code:
if($this->request->is_ajax()){
    $this->load->view('ax_my_view',$data);
}else{
    $this->load->view('my_view',$data);
}

or if you rather decide to let your javascript modify the view from the browser, you would return raw data via json, xml or some other scheme:

Code:
if($this->request->is_ajax()){
    $this->json_send($data);
}else{
    $this->load->view('my_view',$data);
}

For more info about progressive enhancement look up the Hijax framework and any combinations of the keywords "unobtrusive javascript ajax progressive enhancement hijack".

#5
[eluser]Phil Sturgeon[/eluser]
I really dont think it would be as hard as you guys are making it sound. You have normal pages like every application, then you have some ajax methods in your controllers. So have:

Code:
<?php
function index()
{
//load header, main body and footer
}

function something_ajax()
{
//echo ajax code (the code to go into the div)
}
?>

With a basic sort of templating library like the one I made, a simple $wrap option can be set to make this even easier, stops header and footer showing and all you get is the pure HTML to go back into the div.

Not sure why people make such a fuss about this sort of thing. AJAX is just a way of calling page requests and returning them slightly differently...

#6
[eluser]Michael Ekoka[/eluser]
Quote:I really dont think it would be as hard as you guys are making it sound. You have normal pages like every application, then you have some ajax methods in your controllers.

The technique to create an ajax request is easy. Now, having a methodology to integrate and manage Ajax requests over an entire web site in a safe and standardized way, is what may represent a challenge. Which is the reason why it is better to adopt a sound approach to ajax development from the beginning. If you only want to add a few little functionalities here and there, you don't need much protocol, true. But, what about replicating in ajax 80% of already functional processes throughout your app. You can't possibly do this without a plan. Proceed carelessly and a few dozen actions later you end up with an application that breaks in the most unusual ways as soon as the user "tests" it with javascript off.

JosGo came up with a flowchart illustrating his (her?) approach to ajax in the MVC context. I simply shared 3 general methodologies that attempt to minimize the consequences of running a javascript based application on a non-javascript environment. Most people nowadays don't have a real reason to disable js in their browser, but we all know that we should never trust the user.

#7
[eluser]JosGo[/eluser]
If you are talking about web 2.0 items like accordeon's, etc. thepyromaniac is fully right. You can do that using just one controller and the ajax-routines in the controller-class are all about what's on the controller's native screen.
But indeed JosGo his idea is to jump from let's say a screen handling person-data to a screen handling roles to a screen handling grants without rebuilding the entire page. In correct MVC-style that would mean using three controllers and the accompanying (says my dictionary) models and views. In the examples seen thus far nobody does that. I've used it in a non-CI-application and it keeps everything fast for even users with analogue lines.

Apart from that half the solution is already in CI and also in the view-library fom CF mentioned by esra. The $this->load->view can be called using a third boolean parameter. Set it to true and the view-call gives you all output back as a string, which can be sent to a DIV under your control. All examples showed enough about loading, I thought, so I had never looked in the loader-class-documentation.

Remains the second controller-half of my original problem to be solved and of course the new issues raised by _mike_. Never a dull moment.

#8
[eluser]jbowman[/eluser]
No guys, really, this is simple. If you're making AJAX requests, you should have the ability to include a post variable with the request. So in your controller check for that variable.

if (_POST['ajaxRequest'] == true )
{
/* load what my ajax request is expecting, json, xml, piece of html, whatever */
} else {
/* load whatever full page view for people who don't have javascript or whatever */
}


Digg   Delicious   Reddit   Facebook   Twitter   StumbleUpon  


  Theme © 2014 iAndrew  
Powered By MyBB, © 2002-2021 MyBB Group.