tags:

views:

32

answers:

1

Decided to learn ASP.NET MVC and instantly got stuck on something simple.

In Web Forms user controls allowed to separate application into components based on functionality and facilitated reuse. It seems partial views are supposed to do something similar in ASP.NET MVC, but either I am getting this wrong, or each visible page is handled by single controller and it is not possible to delegate certain page portions to separate controllers without hard-coding these controller relationships.

RenderAction can render a partial view and insert resulting HTML in the page, but if we want this view to be refreshed when the user clicks on some link within this view together with the entire page, we need all the partial view links to refer to the parent controller?

For example:

Home\Index.aspx:

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">Home</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
...
<% Html.RenderAction("Index", "Posts"); %>
...

Posts\Index.aspx:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<BlogEngine.Models.PostsViewModel>" %>

    <% foreach(var item in Model.Posts){ %>    
        <p class="postMeta"><%: string.Format("{0} {1}", item.CreatedAt, item.CreatedBy) %></p>
        <h1><%: item.Title %></h1>
        <div><%: item.Content %></div>
    <% } %>

    <% if (Model.CurrentPage > 0){ %>        
        <%: Html.ActionLink("Newer posts", "Index", "Home", new { page=Model.CurrentPage - 1}, null) %>
    <%} %>

    <% if (Model.CurrentPage + 1 < Model.TotalPages) { %>
        <%: Html.ActionLink("Older posts", "Index", "Home", new { page=Model.CurrentPage + 1}, null) %>
    <% } %>

PostsController:

public class PostsController : Controller
{
    private const int PostsPerPage = 2;

    private readonly IPostRepository _postRepository;

    public PostsController()
    {
        ...
    }

    public ActionResult Index(int page = 0)
    {
        var model = new PostsViewModel();
        int totalPages = 1;
        model.CurrentPage = page;
        model.Posts = _postRepository.GetPosts(page, PostsPerPage, out totalPages);
        model.TotalPages = totalPages;

        return PartialView(model);
    }
}

There's got to be a better way than this?

A: 

Hi Arunas,

I don't know if I understand correctly but you could load this Partial View in a using Ajax (by jQuery), and when you need to refresh only this part of content you reload the element. Something like this:

In Javascript:

function LoadComments(page) {
   //It'll return a partial view
   $("#comments").load("<%=Url.Action("Posts", "Index")%>?page=" + page); 
}

$(document).ready(function() {
   LoadComments(0); 
});

Inside of yoru PartialView you need to render a javascript code to call the "reload" of the next (page) content, so call LoadComments(index-page)...

Look the Ajax APi of jQuery: http://api.jquery.com/category/ajax/

Cheers

Felipe
I don't want to rely on JavaScript being enabled. Sure, it's nice to do a partial update via Ajax, but there should be some means to do this without client scripting.
Arunas