Does #Html.Action() and #Html.RenderAction() make another call to the server? - asp.net-mvc-3

This has been bothering me since the first time I saw these methods in the view and I couldn't find any answer on the net.
So if I put this code inside my view
<div id="categories">
#{ Html.RenderAction("Menu", "Nav"); }
</div>
Does that mean that we are making another call to the server after the view is rendered ?
And If not, how does it work ?
Thanks.

No. The view is being generated in it's entirety within the same request. It just means you are rendering the result of an action you've defined in one of your controllers into the current view.

Related

Clarification needed in using Ajax forms and Partial Page

I am newbie to MVC and Web App.
Recently I have went through the article
http://www.c-sharpcorner.com/UploadFile/pmfawas/Asp-Net-mvc-how-to-post-a-collection/
It uses the Ajax Form, to do the partial update towards a particular region alone..
But I have a doubt in that example...
I have seen the partial Page inside the Div with Id "AllTweets"....
<div id="AllTweets">
#Html.Partial("_AllTweets", Model) ***** (XXX)
</div>
And also in the controller action,
try
{
viewModel.Tweets.Add(viewModel.Tweet);
return PartialView("_AllTweets", viewModel); **** (YYYYY)
}
Now my question is,
They are returning the partial view along with the data from the action in the controller.
Whatever the data returned from the controller, the engine will place that data, inside the target div with id "AllTweets"...
But still, why I have to have the statement, #Html.Partial("_AllTweets", Model) inside the Div, since already I am returning the data from the controller...
And also in some of the examples, i have seen the same kind of the code..
But, even if I have removed the code "#Html.Partial("_AllTweets", Model)" inside the div, the code still works fine, and without any problem and i can able to post the data to the action in the controller.
I got totally stuck at this point.
May I kindly know, what is the reason behind it and why so.... So I can understand it more better.
Thanks in advance...
But, even if I have removed the code #Html.Partial("_AllTweets",
Model) inside the div, the code still works fine, and without any
problem and i can able to post the data to the action in the
controller.
Yes it will work fine. The Html.Partial("_AllTweets",Model) renders the partial with the specified model on every page load. After page is loaded, then ajax is used to fill the div with id AllTweets.
Html.Partial("_AllTweets",Model) is usefull when you want to display, for example, already saved tweets from your database to user when the page first loads. And then ajax takes care of later updates.

Update template inside a view rendered from another controller

I am looking for the way to refresh a template inside a view rendered from another controller than the template's controller, I mean:
I got two controllers AdminController & UserController. And two gsps /admin/listUsers & /user/_searchResult.
Then a want to render view listUsers who have inside the template _searchResult and all right.
Now, i want to refresh the template _searchResult, but cant find how. I tryed calling render(view:"/admin/listUsers", template:"/user/_searchResult", model:[searchResult:result])
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers(){
//...
}
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search(){
//search users for the givven params and send result by chain if there's an action or update a template if it's needed
//in my case this method need to update the template _searchResult
}
#Secured(['ROLE_ADMIN'])
def searchResult(){
//...
[searchResult:result]
}
listUsers.gsp
//...
<formRemote name="searchForm" url="[action:"search", controller:"user"]">
//Some fields for the search
//I need to place here some hidden inputs to send which
//template i want to update or action to redirect
</formRemote>
<g:render template="/user/_searchResult"/>
//...
_searchResult.gsp
//Just itterate and print the search result in a table
I hope I have explained the problem correctly, thanks!
I don't think I entirely understand your question, but I think the source of your confusion is that the way you are naming things doesn't follow regular conventions and you're not using the right tools for the job. Let me explain...
The methods on Controllers are called Actions. They send some data (the Model) to a View to be rendered into HTML. Views can be composed from smaller, reusable fragments called Templates. (sorry if I sound like I'm being condescending here, but I'm just trying to make sure we're all on the same page).
Now, what you've called templateA is actually a View, not a Template. You're correct that templateA (your View) can call templateB to render some markup, but then having the templateB try to call a method on another Controller doesn't make sense. That's not how things flow.
If you have some logic that needs to be executed after you've sent your Model to the View, you want to use a Tag Library (http://grails.org/doc/latest/guide/theWebLayer.html#taglibs).
To summarise, here's a quick recap.
A request should only call one Action, which sends the model to only one view.
If you need to reuse logic between Controllers, move that code to a Service.
If you need to reuse markup between Views, move that markup to a Template.
If you have logic that you want to have executed after you've sent the Model to the View, use a Tag Library.
Hopefully this will point you in the right direction.
--- UPDATE ---
OK, with the real code I can see better what you're trying to achieve. Firstly, as you're using the <g:formRemote> tag, you should have a good read of the docs at http://grails.org/doc/latest/ref/Tags/formRemote.html to understand what it does.
What you will have here is 2 separate requests. The first will be a regular page load by your browser, which is handled by the listUsers() action. Once the page is then finished loading, the user will enter a search term and hit the submit button. This will fire off a second ajax request, which will be handled by the search() action. This action could use the _searchResult.gsp template to render a HTML table to display the search results. When the browser get this, it will insert it into the DOM where you've told it to put it using the "update" attribute of the <g:formRemote> tag.
The important thing here is that from the server's perspective, these are 2 separate requests that are completely independent. They both first call an action, then send a model (a Map containing some data) to a view, which renders/merges the data with HTML and sends it back to the browser.
The difference between the 2 is that the first is a complete page load by the browser, whereas for the second request, the browser only loads a small chunk of HTML (the search results table) and updates the page content without reloading it.
So your code would look more like this...
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers() {
render(view:"/admin/listUsers")
}
listUsers.gsp
<g:formRemote name="searchForm" update="insertSearchResultsHere"
url="[controller: 'user', action:'search']">
<input name="searchTerm" type="text" />
</g:formRemote>
<div id="insertSearchResultsHere"></div>
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search() {
// use the search term to get a List<User>
render(template: "/user/searchResult", model: [users: users])
}
_searchResult.gsp
<table>
<g:each var="user" in="${users}">
%{-- Iterate through your search results --}%
</g:each>
</table>
I solved it by placing the attribute update and rendering the template alone:
gsp:
<formRemote name="searchForm" url="[action:"search", controller:"user"]" update="divToUpdate">
//Some fields for the search
</formRemote>
<div id="divToUpdate">
<g:render template="/user/_searchResult"/>
</div>
Controller:
def search(){
render(template:"/user/_searchResult", model:[searchResult:result])
}
When i asked this question, i was new on Grails community and i was confused with the use of remoteFunction and tags that use it like remoteForm. But i had this confusion because of i had not read the documentation. So in my case, the solution was search for documentation about how to use remote tags and render. Thanks to #AndrewW for show me the way.

Complex Pages and Data

I am trying to figure out the best way to handle pages in our application like the dashboard, where there are a number of different panes with various bits of data in it.
The main issue is that the controller action becomes unwieldy when the page needs so much data. The client side can be broken up into partial views to make it more manageable, but all the data still needs to passed into the View to be distributed down to the partials. Or does it?
Obviously some of the panels could be loaded dynamically or something like that, but I was looking for the best approach besides loading individual piece of the page from the browser.
Have you considered using Html.Action in your view? You would pass enough data to the main view to enable you to give the required data to each of the child actions. The main action would render the main view which would call actions for each pane. Each action would be responsible for that pane, rendering its own partial view. Additionally, you could call back to each of the child actions directly from the client to update that pane dynamically via AJAX.
Here's an example with some mocked up actions of what your main view might look like.
<div class="left-pane">
#Html.Action("Summary", new { id = Model.ID } )
</div>
<div class="middle-pane">
#Html.Action("PendingItems", new { id = Model.ID, timestamp = DateTime.Now } )
</div>
<div class="right-pane">
#Html.Action("News")
</div>

Refreshing Partial View in MVC 3

I have a partial view that I have included on my _Layout.cshtml. It simply has a javascript function that changes an image based on the state of my system. I don't need to reload any data, I don't need to go to the code of the controller for anything, I simply need to reload that partial view.
I tried many of the examples that I found here but couldn't get any of them to work. I felt as if they were too complex for what I was doing anyway. Any guidance would be appreciated.
Thanks,
Steve
If the partial is loaded into the layout directly then there's no straightforward way to refresh it, because it's basically a part of the complete rendered page.
Your best bet is to render the partial using $.load or whatever equivalent you have available by hitting a controller method and rendering the result into a container (like a div). You would have to do this within a script that is loaded with the layout itself, by observing document.ready or something like that. Once you have that in place then it's trivial to keep reloading or refreshing the contents by hitting the controller method as many times as you need. For example in jQuery:
$(document).ready(function () {
RefreshPartial();
window.setInterval(RefreshPartial, 10000);
});
function RefreshPartial() {
$('#container').load('/some/controller/endpoint', {parameters});
}
This will call the controller method, and set the inner contents of the element identified with #container. You can call RefreshPartial as many times as you want.
Partial views only exist on the server. The only way to "refresh" the partial is to go back to the server to get it again.
Obviously, you must be doing something in the partial that needs refreshing. Whatever that is, should be callable from javascript to do the refresh.

What are Partial Views?

I've been using Codeigniter in order to get accustomed to the Model-View-Controller architecture, and to try and speed up the process of making and implementing sites.
I keep seeing references to "Partial Views" but can't find a definition for the term.
Can anyone tell me what a partial view is, and where it is used?
A partial view is just a sub-view that you can include in a parent view. Let's take a look at a common example:
// Controller:
$data['myvar'] = array('element1', 'element2', 'element3');
$this->load->view('myview', $data);
// Myview:
<ul>
foreach ($myvar as $var) {
$this->load->view('partialview', array('var', $var));
}
</ul>
// Partialview:
<li><?= $var ?></li>
This is useful to repeat content according to a list.
Note that nothing differs between a view and a partialview, it's just the way you include it that defines the term.
The best way to describe a "partial view" is to think of it as a template, it displays a chunk of html with Model data passed to it.
Good examples of where to use one would be where you plan on displaying the same html over and over, like a menu or a page header or even better yet use them to display content requested using ajax.
Basically you call an action on the controller that returns the partial view from lets say jQuery and then put the returned markup into a select or div tag. Here is an example of doing that from my blog easy ajax with aspnet mvc and jquery, yes I know it asp.net mvc not php and codeigniter, but the principal is the same.

Resources