domingo, 21 de julio de 2013

Vista Parcial (PartialView)

Introducción:
Siempre que realizamos una consulta y queremos ver datos específicos , enviamos parámetros para que nuestra consulta sea mas precisa, y se estarán preguntando como se podría hacer eso en MVC , para eso usaremos las vistas parciales o PartialView que nos ayudarán dinámicamente a mostrar datos según parámetros.
Como ejemplo usaremos una consulta de detalles de pedidos que recibirá como parámetro el id de pedido de la bd Neptuno.

Que es un PartialView?
Un PartialView es una vista que podemos renderizar en otra vista , esta otra vista se le llama comúnmente como Vista padre, asi que por lógica una vista padre puede tener varias Vistas parciales. La vista principal es la que mandará los datos de parámetros para que las vistas parciales muestren resultados segun esos parámetros, estas pueden actualizarse mas no la vista principal, en resumen los PartialView dependen de una vista principal o vista padre para mostrar sus resultados.
Si quieres saber mas acerca de esto puede revisar. Partial View C#

1. Creamos los modelos, uno para llenar un Select con los id de pedidos y otro que recibirá los datos que se mostrarán.
  
public class PedidosModels
    {
        public int IdPedido { get; set; }
    }

    public class DetallePedidosModels
    {
        public int IdPedido { get; set; }
        public string NombreProducto { get; set; }
        public decimal PrecioUnidad { get; set; }
        public int Cantidad { get; set; }
        public decimal Total { get; set; }

    }
2. Ahora en el controlador , realizamos las consultas correspondientes para la vista principal y el partial view.
public class DetallePedidosController : Controller
    {
        NeptunoEntities db = new NeptunoEntities();

        public ActionResult Pedido()
        {
            var Pedidos = from p in db.Pedidos
                          where p.IdPedido < 10260
                          select new PedidosModels
                          {
                              IdPedido = p.IdPedido
                          };
            var ListadoPedidos = Pedidos.Distinct().ToList();
            ViewBag.ListadoPedidos = ListadoPedidos;
            return View();
        }

        public ActionResult DetallePedido(int IdPedido)
        {
            var DetallePedido = from p in db.Pedidos
                                join dp in db.Detalles_de_pedidos on p.IdPedido equals dp.IdPedido
                                join pr in db.Productos on dp.IdProducto equals pr.IdProducto
                                where p.IdPedido == IdPedido
                                select new DetallePedidosModels
                                {
                                    IdPedido = p.IdPedido,
                                    NombreProducto = pr.NombreProducto,
                                    PrecioUnidad = dp.PrecioUnidad,
                                    Cantidad = dp.Cantidad,
                                    Total = (dp.PrecioUnidad * dp.Cantidad)
                                };
            var ListadoDetalle = DetallePedido.ToList();
            ViewBag.ListadoDetalle = ListadoDetalle;
            return PartialView(ViewBag.ListadoDetalle);
        }

    }
Si se dan cuenta , la action "DetallePedido" , ahora debe recibir un parámetro el cual es "IdPedido" , asi que mediante ese parametro mostrará los datos , si se fijan en el "where" , veran que alli le mando la condición y también como retorno ya no mando "View" , ahora es "PartialView". 3. Crear una Vista Parcial de una acción. Para crear una vista parcial , encima del nombre de la acción, damos click derecho y seleccionamos "Agregar Vista".


Luego debemos de habilitar el check de "Crear como Vista Partial".


3. Construyendo la vista parcial. Si se dan cuenta una vista parcial no es muy distinta que una vista principal, pero tiene una gran diferencia , la cual es que la vista principal tiene referencia el Layout y una vista parcial no lo tiene. El Layout guarda los un diseño maestro para mostrarlos en todas las vistas padres, es el equivalente a Master Page en asp.net.
@using Aplicacion_PartialView.Models;
<table>
<thead>
    <tr>
        <th>IdPedido</th>
        <th>NombreProducto</th>
        <th>PrecioUnidad</th>
        <th>Cantidad</th>
        <th>Total</th>
    </tr>
</thead>

<tbody>
@foreach (var d in ViewBag.ListadoDetalle as List<DetallePedidosModels>)
{
    <tr>
        <td>@d.IdPedido</td>
        <td>@d.NombreProducto</td>
        <td>@d.PrecioUnidad</td>
        <td>@d.Cantidad</td>
        <td>@d.Total</td>
    </tr>

}
</tbody>
</table>

4. Construyendo la Vista Principal , llenamos el select con los IdPedidos mediante un foreach , y ponemos un boton al lado para llamar al PartialView con el IdPedido seleccionado.
@using Aplicacion_PartialView.Models;

<label>Pedidos</label>
<select id="IdPedidos">
@foreach (var p in ViewBag.ListadoPedidos as List<PedidosModels>)
{ 
<option value="@p.IdPedido">@p.IdPedido</option>
}
</select>
<input id="BuscarDetalle" type="button" value="Buscar"/>

@*Este Div contendra el resultado del PartialView.*@
<div id="DetallePedido">

</div>

En el DIV con id "DetallePedido" renderizaremos el partialView , usando JQUERY y utilizaremos como selector el Id del boton de la siguiente manera.
<script type="text/javascript">

    $("#BuscarDetalle").click(function () {
        $("#DetallePedido").load('@Url.Action("DetallePedido","DetallePedidos")', {IdPedido:$('#IdPedidos').val()})
    });

</script>

Usando la funcion "load" , renderizo el resultado dentro del DIV. Si lo notan ,ahora envio un parametro a la accion , "{IdPedido:$('#IdPedidos').val()}", capturando el valor del select mediante su selector.
Resumiendo , cada vez que presione el boton , llamará al PartialView segun el parametro seleccionado en el Select.

Aquí dejo la solución , por si deseas descargarlo.

2 comentarios:

  1. Excelente Muchas gracias por el aporte

    ResponderEliminar
  2. Interesante artículo, gracias, ¿de donde podría descargar la BBDD Neptuno para reproducir el ejemplo en local?

    ResponderEliminar