ASP .NET MVC 4 - Exibindo dados JSON usando Knockout


Neste artigo vou mostrar como usar Knockout para exibir dados JSON em uma aplicação ASP .NET MVC4.

No meu primeiro artigo sobre Knockout eu apresentei o recurso e mostrei um exemplo usando HTML, hoje vamos dar mais um passo e mostrar como usar o Knockout com ASP .NET MVC.

A Knockout(KO) é uma biblioteca JavaScript que ajuda você a criar interfaces de usuário com edição que usam um modelo de dados subjacente limpo. Toda vez que você tiver seções de interface do usuário que sofrem atualizações dinâmicas a KO pode ajudar na implementação de forma simples e fácil de manter.

A seguir um resumo das principais características da Knockout:

Criando o projeto MVC4 com Knockout

Abra o Visual Studio 2012 Express for web e clique em New Project;

A seguir selecione o template Visual C# -> Web -> ASP .NET MVC 4 Web Application informando o nome Knockout_Mvc4;

A seguir selecione o template Internet Application e o engine Razor e clique em OK;

Será criado um projeto MVC4 com toda a estrutura e recursos prontos. Dessa forma veremos a estrutura da aplicação já contendo as pastas e os recursos que iremos usar em nosso projeto.

A pasta Scripts já contém as bibliotecas javascript do jQuery e o Knockout; a pasta Controllers já contém o controlador HomeController que iremos alterar; a pasta Views/Home já contém o arquivo Index.chstml que será usada como a nossa view.

Vamos agora partir para ajustar o projeto criado às nossas necessidades.

Definindo o Model

Clique com o botão direito da pasta Models e selecione Add->Class;

A seguir informe o nome Cliente.cs e digite o código que define a classe Cliente com Nome e Email:

namespace Knockout_Mvc4.Models
{
    public class Cliente
    {
        public string Nome { get; set; }
        public string Email { get; set; }
    }
}

Ajustando o Controller

Na pasta Controllers abra o arquivo HomeController e altere o seu código conforme abaixo:

using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Knockout_Mvc4.Models;

namespace Knockout_Mvc4.Controllers
{
    public class HomeController : Controller
    {
        [AllowAnonymous]
        public ActionResult Index()
        {
            ViewBag.Message = "Usando Knockoutjs com Asp.net MVC4";
            string verChave = string.Empty;
            if (Request.Form.AllKeys.Count() > 0)
            {
                if (Request.Form.AllKeys.Contains("verNome"))
                    verChave = Request.Form["verNome"].ToString();
                if (verChave.Equals("JSON"))
                    return GetCliente();
                else
                    return null;
            }
            return View();
        }

        public JsonResult GetCliente()
        {
            List<Cliente> clientes = new List<Cliente>
                              {
                                  new Cliente(){Nome="Macoratti", Email="macoratti@yahoo.com"},
                                  new Cliente(){Nome="Janice", Email="janjan@bol.com.br"},
                                  new Cliente(){Nome="Jefferson", Email="jef@net.com.br"},
                                  new Cliente(){Nome="Jessica", Email="jessica@uol.com.br"},
                                  new Cliente(){Nome="Miriam", Email="mimi@uol.com.br"},
                                  new Cliente(){Nome="Marcia", Email="marcia@bol.com.br"},
                                  new Cliente(){Nome="Mario", Email="mario@zipmail.com.br"},
                              };
            System.Web.Script.Serialization.JavaScriptSerializer jSearializer = new System.Web.Script.Serialization.JavaScriptSerializer();
            string jsonString = jSearializer.Serialize(clientes);
            return Json(jsonString, JsonRequestBehavior.AllowGet);
        }

    }
}

Neste Controlador temos o método Index() que irá chamar a respectiva view na pasta /Views/Home.

O método Index() chama o método GetCliente() onde definimos alguns nomes e emails dos clientes e retornamos os dados no formato JSON

Definindo a View

Agora na pasta /Views/Home abra o arquivo Index.cshtml e altere o seu código como mostrado a seguir:

<script src="~/Scripts/knockout-2.1.0.js"></script>
<script src="~/Scripts/jquery-1.7.1.js"></script>

@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @id = "macForm" }))
{
    @Html.Hidden("verNome");
    <div id="jsonDiv">
        <input id="btnGetJSON" type="button" value="Obter dados JSON e exibí-los usando Knockoutjs" onclick="javascript: GetJSONData('JSON', 'macForm')" /><br />
        <table border="1">
            <thead>
                <tr>
                    <th>
                        Nome
                    </th>
                    <th>
                        Email
                    </th>
                </tr>
            </thead>
            <tbody data-bind="foreach: clientes">
                <tr>
                    <td data-bind="text: Nome">
                    </td>
                    <td data-bind="text: Email">
                    </td>
                </tr>
            </tbody>
        </table>
    </div>   
}
<script src="~/Scripts/Macoratti.js"></script>

A nossa view Index.cshtml exibe os dados obtidos via JSON usando os recursos do Knockout.

Precisamos criar agora no arquivo javascript Macoratti.js onde iremos definir o Model-ViewModel e usar os recursos do jQuery e Knockout.

Vamos criar o arquivo javascript na pasta Scripts do projeto. Para isso clique com o botão direito do mouse sobre a pasta Scripts e selecione Add->New Item;

A seguir selecione o template JavaScript File e informe o nome Macoratti.js ou outro nome a seu critério:

Digite o código abaixo neste arquivo:

function GetJSONData(hiddenValue, formID) {
    $("#verNome").val(hiddenValue);
    var form = $('#' + formID)
    $.ajax({
        url: form.attr('action'),
        type: "POST",
        data: form.serialize(),
        success: function (response) {
            if (hiddenValue == 'JSON') {
                // parseJSON
                response = $.parseJSON(response);
                //Pega a div e chama o método knockout
                var dn = document.getElementById('jsonDiv');
                var x = ko.contextFor(dn);
                x.$root.getClientes(response);
            }
        },
        error: function (error) {
            alert(error.status + "<--e--> " + error.statusText);
        }
    });
}

function Cliente(pnome, pemail) {
    this.Nome = pnome;
    this.Email = pemail;
}

function clienteVM() {
    var self = this;
    self.Nome = ko.observable();
    self.Email = ko.observable();
    self.clientes = ko.observableArray([]);

    self.getClientes = function (data) {
        self.clientes.removeAll();
        $.each(data, function (key, val) {
            self.clientes.push(new Cliente(val.Nome, val.Email));
        });
    };
}
$(document).ready(function () {
    var dn = document.getElementById('jsonDiv');
    ko.applyBindings(new clienteVM(), dn);
});
O arquivo Macoratti.js é onde os dados voltam a partir do controlador sendo vinculados a nossa View.

A função clienteVM contém a propriedade name vinculada a UI. O objeto Clientes é um array observávelgetClientes é um método interno chamado quando os dados são recebidos a partir da interface do usuário.

No método GetJSONData() fizemos uma chamada ajax para o controlador e recebemos os dados JSON.

Agora para ligar esses dados com a interface do usuário é importante para obter o contexto da div onde você tem que ligar os dados. Depois de obter o objeto de contexto chamamos o método interno getClientes() de clienteVM.

Este método percorrer os dados JSON recebidos inserindo-os na a matriz observável. Como os dados estão sendo inseridos no array observável a view vai ficar atualizada. É assim que knockoutjs funciona.

Agora basta executar o projeto que irá apresentar a seguinte página:

Clicando no botão - Obter dados JSON e exibí-los usando Knockoutjs - iremos obter a página abaixo onde vemos a exibição dos dados obtidos:

Dessa forma, usando um exemplo bem simples vimos como exibir dados JSON com Knockout.

A Knockoutjs não compete com jQuery ou outras APIs similares e assim Knockoutjs fornece uma maneira complementar, de alto nível de vincular um modelo de dados com a interface.

Pegue o projeto completo aqui: Knockout_Mvc4.zip (sem as referências)

João 6:63 O espírito é o que vivifica, a carne para nada aproveita; as palavras que eu vos tenho dito são espírito e são vida.

João 6:64 Mas há alguns de vós que não crêem. Pois Jesus sabia, desde o princípio, quem eram os que não criam, e quem era o que o havia de entregar.

Referências:


José Carlos Macoratti