Hola, una característica de ASP.NET MVC que me gusta bastante son las vistas parciales, y lo mejor de todo es que podemos usarlas en conjunto con AJAX de una manera realmente sencilla, ya que el mismo framework ofrece helpers que permiten realizar tareas comunes como la que vamos a ver en este post: cargar una vista parcial.

Vamos a realizar un pequeño formulario del tipo maestro – detalle, la idea es simular las ventas por mes, y en el detalle visualizar que producto se vendió por mes y su valor (tendremos datos estáticos, pero la idea es que se conectará con un repositorio de datos).

Primero vamos a definir dos clases como modelo (las clases son sencillas para realizar el ejemplo):


public class VentasMes
{
    public int Id { get; set; }
    public string Mes { get; set; }
    public int Valor { get; set; }
    public ICollection DetalleMes { get; set; }
}

public class DetalleMes
{
    public int Id { get; set; }
    public string Producto { get; set; }
    public int Valor { get; set; }
    public VentasMes VentasMes { get; set; }
}

Es necesario añadir una referencia al js jquery.unobtrusive-ajax, primero vamos a crear el bundle correspondiente (si usas la plantilla de Internet Application ya se tiene definida):


bundles.Add(new ScriptBundle("~/bundles/jqueryval")
    .Include( "~/Scripts/jquery.unobtrusive", "~/Scripts/jquery.validate"));

y luego la añadimos en el _Layout.cshtml:


@Scripts.Render("~/bundles/jqueryval")ry.validate"));

Ahora, creamos el controllador VentasController con la acción List y algunos datos iniciales:


public class VentasController : Controller 
{ 
    private readonly List ventasMes = new List() 
    { 
        new VentasMes() { Id = 1, Mes = "Enero", Valor=200000, DetalleMes = new List()
            { 
                new DetalleMes(){ Id = 1, Producto = "Producto 1", Valor = 50000}, 
                new DetalleMes(){ Id = 1, Producto = "Producto 2", Valor = 50000}, 
                new DetalleMes(){ Id = 1, Producto = "Producto 3", Valor = 50000}, 
                new DetalleMes(){ Id = 1, Producto = "Producto 4", Valor = 50000} 
            } 
        }, 
        new VentasMes() { Id = 2, Mes = "Febrero", Valor=200000, DetalleMes = new List()
            { 
                new DetalleMes(){ Id = 1, Producto = "Producto 1", Valor = 100000}, 
                new DetalleMes(){ Id = 1, Producto = "Producto 2", Valor = 100000} 
            } 
        }
    }; 

    public ActionResult List() 
    { 
        return View(ventasMes); 
    } 
}

Y ahora creamos la vista correspondiente List.cshtml:


@model IEnumerable<PartialView_Ajax.Models.VentasMes>

@{
    ViewBag.Title = "Resumen";
}

<h2>Resumen Ventas</h2>
<table>
    <tr>
        <th>
            @Html.DisplayNameFor(model => model.Mes)
        </th>
        <th>
            @Html.DisplayNameFor(model => model.Valor)
        </th>
        <th></th>
    </tr>

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Mes)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Valor)
        </td>
        <td>
            @Ajax.ActionLink("Detalles", "ViewDetails", new { id = item.Id }, new AjaxOptions { UpdateTargetId="divDetails" })
        </td>
    </tr>
}

</table>
<div id="divDetails"></div>

Como se puede observar, se esta haciendo uso del helper de Ajax.ActionLink, este tiene varios constructores,sin embargo el que estamos utilizando requiere como primer parámetro el texto del link, el segundo es la acción del controlador que se ejecuta, el tercero los datos enviados a la acción y el cuarto permite definir varias opciones, en este caso solo utilizo UpdateTargetId el cual permite definir el id del control en donde mostrar el resultado de la acción, en este caso será la vista parcial, y entonces la acción:


public ActionResult ViewDetails(int id) 
{ 
    var detalle = ventasMes
        .Where(c => c.Id == id) 
        .Select(c => c.DetalleMes) 
        .FirstOrDefault(); 

    return PartialView("_Details",detalle); 
}

La diferencia a una acción normal es que se retorna PartialView en lugar de View, y allí estamos definiendo el nombre de la vista parcial (_Details) y como segundo parámetro el modelo, entonces la definición de la vista parcial:

@model IEnumerable<PartialView_Ajax.Models.DetalleMes>

<fieldset>
    <legend>Detalle x Mes</legend>
    <ul>
        @foreach (var item in @Model)
        {
            <li>
                <p>@item.Producto (@item.Valor.ToString("c"))</p>
            </li>
        }
    </ul>
</fieldset>

Y listo, finalmente lo que vamos a obtener es:

image

Espero les haya gustado el post, les dejo el código del ejemplo:

Descarga el ejemplo!

Saludos.