#1
  1. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533

    MVC - What is the view when using Ajax?


    For a traditional page, my view sends user intent to the controller, the controller gets the data from the model and sends the data to the view and the view displays the data. Obviously, HTML falls strictly under the domain of the view. So would adding dollar signs and the like. Maybe a little less black and white, but I am assuming formatting dates would as well. The controller and model are both server-side, and the view is also generated server-side.

    Now I have an ajax request. The view running on the client sends intent to the controller located on the server which gets data from the model and ??? Is part of the view located on the server, or is all of it located on the client? I would think that generating HTML would be best on the client. Maybe adding dollar signs and commas would as well? What about formatting dates to US format? Similarly, if US format dates were used in the client view but not in the model, should the client first convert them before sending them to the server?

    I realize that some of this might be personal opinion, but would would appreciate understanding what is typically done.

    Thanks
  2. #2
  3. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    If the AJAX returns HTML then it's just another view.

    If it returns JSON (my preferred method) then what you do depends on the framework. I would like to see a special JSON view renderer extend the normal view renderer, and rather than use a PHP script as output it json_encode()s the view data. Otherwise you could have an actual view file but all it does it output the JSON.

    If it's a mix then you would use "partial views" (as I know them). At the top level it's JSON; somewhere within the object is the HTML which you rendered separately.
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    Thank you requinix,

    I am a little confused by your response. What is "it" when you state "then it's just another view" or "If it returns JSON"? Is your "special JSON view renderer" server-side or client-side? I do, however, get your concept of "partial views"

    Maybe a little help describing how my mind works regarding MVC will help, however, be aware I have no formal training and read little on the subject, so anything I say can be horribly wrong.

    I typically use my server view to create the initial page HTML as well as any supporting HTML for dialogs, etc. For instance, if I have a button on the page that pops up a dialog, the dialog HTML is already rendered on the page but hidden. Sometimes the dialog needs extra content to populate it (maybe there is one button per row which each need their own data on the dialog) in which I would do a quick GET request and either return JSON or just text if it was very simple (now that I think about it, I use the controller to echo the json_encode). I then have view functionality which takes that JSON and displays it as appropriate.
  6. #4
  7. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    Originally Posted by NotionCommotion
    I am a little confused by your response. What is "it" when you state "then it's just another view" or "If it returns JSON"?
    The first "it" is an abstract thing representing the solution to the problem and the second "it" is the AJAX.
    Rephrased, if your AJAX returns HTML then there's no real difference between the AJAX MVC process and the regular HTML MVC process in that they both involve rendering an HTML view. There is a client-side difference though: instead of a browser rendering the HTML as a new page, your Javascript captured the HTML on the same page and did whatever it wanted.

    Originally Posted by NotionCommotion
    Is your "special JSON view renderer" server-side or client-side?
    Server-side. Odds are that you have some sort of view rendering class. If not then consider it. That class would normally look up the view file, include() or whatever it, and return the output.
    For JSON you can subclass that renderer, and instead of including and outputting a file, it outputs the JSON-encoded version of the view's variables. So like normally you might have a $this->view->title="Foo" and the HTML view has
    Code:
    <title><?php echo $this->title; ?></title>
    Instead the JSON view renderer outputs
    Code:
    {"title":"Foo"}
    An alternative to a subclass is a simple "is the response JSON" flag: if so then the view renders JSON of the data, if not then it does what it would normally do.

    Originally Posted by NotionCommotion
    ...
    What you've described is something that's simple enough where you only need to pass back to the client a bit of information, which then stitches it into place. This whole thing I've been talking about is for more complicated things where you don't want to have to, essentially, include the view in the Javascript or as a hidden element.
    So like rather than have the dialog HTML already rendered but hidden, the AJAX actually passes back the HTML to render and the AJAX can very dumbly just display it (or load it into some element and display that).

    It's a question of where you want to keep the view logic. If you can put it in Javascript or mostly-prerendered HTML then okay, but if that gets complicated then you can keep the logic server-side and make the client render what the server says.

    For example, number formatting. If you put all the logic in the client then you need the Javascript to know the formatting rules for the user. That's additional work for the client. At the expensive of more overhead, you can keep all the know-how and rules and work on the server and limit the Javascript to "do an AJAX request and stick the contents in this DIV over here". Less work for the client.
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    Thanks requinix, great post.

    Thank you for defining who "it" is . Good explanation on why there is not a difference between the AJAX MVC process and the regular HTML MVC process under certain circumstances.

    Yes, I have a class which deals with rendering normal (and not JSON) views. It is my own creation and nothing special, but it does what it needs to do. I understand how the server will just output some json_encode(stuff). You go own to say that I might "For JSON you can subclass that renderer, and...". That subclass is just a bunch of JavaScript that deals with the server data? I understand your alternative to the subclass which just responds yes/no based on the json response.

    In regards to my simplicty of my design, I agree it does not need to be as complicated as what you are talking about, but appreciate being consistant on approach, and am seriously considering doing exactly as you suggest. My original question was where should the view exist, and having it sometimes here and sometimes there hurts my head.

    In regards to who does the work, I suppose you make someone else (i.e. the client) do it when ever possible.
  10. #6
  11. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    Originally Posted by NotionCommotion
    You go own to say that I might "For JSON you can subclass that renderer, and...". That subclass is just a bunch of JavaScript that deals with the server data?
    Still server-side.

    Examples:
    PHP Code:
    class ViewRenderer {

        protected 
    $data = array();

        public function 
    __construct($view) {
            
    // ...
        
    }

        public function 
    __get($name) {
            return 
    $this->data[$name];
        }

        public function 
    __set($name$value) {
            
    $this->data[$name] = $value;
        }

        public function 
    render($output true) {
            
    $output || ob_start();
            include 
    $this->view;
            return 
    $output ?: ob_get_clean();
        }

        public function 
    setData(array $data) {
            
    $this->data $data;
        }


    PHP Code:
    class JsonViewRenderer extends ViewRenderer {

        public function 
    render($output true) {
            if (
    $output) {
                echo 
    json_encode($this->data);
                return 
    true;
            } else {
                return 
    json_encode($this->data);
            }
        }


    Then the controller knows which subclass to go with, however it works. The .NET MVC 3 method (IIRC) is like
    PHP Code:
    class SomeController extends Controller {

        public function 
    someAction() {
            
    $this->viewdata->title "Title";
            return 
    $this->view();
        }

        public function 
    someAjaxAction() {
            
    $this->viewdata->response "Okay";
            return 
    $this->json();
        }


  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    Gotcha,

    Much of my MVC philosophy follows this, but I definitely have some homegrown ideas in mine. Some of my ideas are loosely based on Joomla's implementation which I was using several years ago. One of these days, I probably should better understand how the rest of the world utilizes MVC and migrate my approach.

    Thanks again!
  14. #8
  15. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    MVC is just about separating the models, views, and controllers, and you already get it. Beyond that it's a matter of writing nice looking and functional code and there are a million options for how to do that.
  16. #9
  17. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    I could use a little more discussion regarding how HTML is transmitted with the Ajax call (i.e. partial view).

    Let's say desired functionality consist of a button that when clicked, popups up a dialog. The dialog has a bunch of rows each with a name and a delete button.

    Client sends Ajax request to server, the server returns JSON which includes both some data and as well as some HTML. The JavaScript on the client takes the HTML which is included in the JSON, appends it to the DOM, and updates it as needed with the data. Upon closing the dialog, the DOM element is removed and as such the HTML must be downloaded again if the dialog is reopened.

    Do I have this correct? Is JavaScript also ever downloaded within the JSON?
  18. #10
  19. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    If you can be reasonably sure that the HTML hasn't changed since the last time the dialog was opened (you can do an AJAX for that) then there's no need to remove it when closed.

    But basically, yes. You get HTML from the server and display it.

    As for code, I've never seen literal Javascript code returned. The calling code should be written so that it handles the various possibilities, not the response. However I've seen (and used myself) HTML which includes <script> tags. Not as the meat of the response but as a supplemental thing like... I don't remember, it's been a while.
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    As for code, I've never seen literal Javascript code returned.
    A while ago I created (but never did anything with) a website which allows the user to enter beer ingredients and discover what the beer would look and taste like http://www.tapmeister.com/. Now you have seen literal JavaScript code returned! It was before I understood Ajax, and instead the client just asked the server server to download some JavaScript which it in turn executed. I am not saying I agree with my implementation, but I have often wondered whether the server should have some control over which JavaScript a particular client accessed.
  22. #12
  23. Did you steal it?
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    13,959
    Rep Power
    9397
    It might be a reasonable solution, but somewhere it'll involve eval()ing code and I don't like doing that on principle.
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Sep 2006
    Posts
    1,916
    Rep Power
    533
    Maybe not a reasonable solution, but doesn't involve eval()ing code in the normal sense.
    Code:
    var script = document.createElement( 'script' );
    //Be sure whacked.php includes header( 'Content-Type: text/javascript' );
    script.src = 'whacked.php?data=' + someData;
    document.getElementsByTagName( 'head' )[0].appendChild( script );

IMN logo majestic logo threadwatch logo seochat tools logo