Asp.net MVC + Knockoutjs – parte I

Graça a grandes aplicações como Facebook,Twitter e Google Plus, tem gerado uma grande influência na maneira de  desenvolvermos nossas aplicações , priorizando uma interface mais sofisticada e intuitiva.

Para trabalhar com a nossa UI, vamos utilizar a biblioteca KnockoutJS, knockout é uma biblioteca de Java Script que nos ajuda a criar  interfaces de usuário com um modelo de dados limpo.

Toda vez que temos seções de interface de usuário que a atualização é dinâmica KO pode ajudar de forma muito mais simples e sofisticada.

Para saber mais sobre a biblioteca acesse o site http://knockoutjs.com.

O foco do post é consumir os dados de uma WEB API através do Jquery e implementarmos a nossa interface com o Knockout JS.

 

Vamos criar uma projeto do tipo Asp.net MVC e para esse exemplo vamos utilizar o tamplete empty.

Como escolhemos a opção empty precisamos adicionar no projeto as bibliotecas Jquery e Knockout JS.

Para adiciona-las vamos utilizar o Nuget, caso você nuca utilizou esse grande recurso disponível no Visual Studio.

Basta seguir os passos como na imagem abaixo.

 

Agora precisamos escrever os seguintes comandos no console.

 

 

Depois de executar os comandos note que foi criada uma pasta com o nome Script na nossa solução e dentro dela o Nuget adicionou as bibliotecas Jquery e Knockoutjs.

Vamos criar dentro da pasta Model uma class  chamada “Funcionario” segue abaixo a estrutura da class.

     public class Funcionario
    {
        public int codigo { get; set; }
        public string nome { get; set; }
        public string email { get; set; }
        public string cargo { get; set; }
    }

Agora precisamos criar um controle FuncionarioController dentro da pasta Controllers do tipo API e  precisamos escolher o template do tipo  “API controller with empty read/write actions”.

Segue abaixo a estrutura do controle  FuncionarioController.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using Mvcknockout.Models;

namespace Mvcknockout.Controllers
{
    public class FuncionarioController : ApiController
    {
       
        public List GetAll()
        {
            var cliente = new List()
            {
                new Funcionario {codigo =1,nome="Juliano Sales",email="juliano.salesg@gmail.com",cargo="Desenvolvedor"},
                new Funcionario {codigo =2,nome="Bruno",email="bruno@gmail.com",cargo="Gerente de Projeto"},
                new Funcionario {codigo =3,nome="Fernanda",email="fernanda@gmail.com",cargo="Gerente de RH"},
                new Funcionario {codigo =4,nome="Lucas",email="lucas@gmail.com",cargo="Gerente Administrativo"}
            };

            return cliente;
        }

        public ListGet(string pesquisa)
        {
            var cliente = new List()
            {
                new Funcionario {codigo =1,nome="Juliano Sales",email="juliano.salesg@gmail.com",cargo="Desenvolvedor"},
                new Funcionario {codigo =2,nome="Bruno",email="bruno@gmail.com",cargo="Gerente de Projeto"},
                new Funcionario {codigo =3,nome="Fernanda",email="fernanda@gmail.com",cargo="Gerente de RH"},
                new Funcionario {codigo =4,nome="Lucas",email="lucas@gmail.com",cargo="Gerente Administrativo"}
            };

            if (pesquisa != null && pesquisa !="")
                return cliente.Where(l => l.nome.ToUpper().Contains(pesquisa.ToUpper())).ToList();
            else
                return cliente;
        }
    }
}

Agora precisamos criar um controle chamado HomeController e na opção template  “Empty MVC controller”.

Segue abaixo a estrutura do controle HomeController

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

namespace Mvcknockout.Controllers
{
    public class HomeController : Controller
    {
        //
        // GET: /Home/

        public ActionResult Index()
        {
            return View();
        }

    }
}

No controle HomeController precisamos criar uma View para a ActionResult Index.

Segue abaixo a estrutura do projeto.

Precisamos entender que o Knockout faz a ligação do nosso modelo de dados coma a nossa Interface.

Segue um exemplo abaixo:


Para mapear o modelo coma a UI, a biblioteca Knockout utiliza o prefixo data-bind

Na View  Index.cshtml precisamos adicionar o código abaixo.



Index
Código Nome E-mail Cargo

Como assim foreach ????no html, tudo sera explicado abaixo.
Primeiro antes da explicação vamos conhecer o java script responsável por ligar nosso model ao html.

  

No java script criamos uma função chamada viewModelFuncionario
e dentro dessa função nos temos uma variável chamada pesquisa essa variável está vinculada no input funcionário ou seja toda vez que um usuário clicar no botão Pesquisa o valor da pesquisa será atribuído a variável self.pesquisa .
O objeto self.ListaFuncionario, está recebendo o valor ko.observableArray();, ele ficará atrelado ao estado do objeto, mais detalhes sobre observableArray() pode ser consultada no site da biblioteca apresentada.
Na próxima linha nos temos uma função chamada this.Pesquisa e toda vez que ela e executada ela chama uma outra função que é responsável por limpar o objeto self.ListaFuncionario.
A função getJson que retorna um json que percorremos utilizando o $.each e acada item adicionamos no objeto self.ListaFuncionario.
No final da função nos temos uma outra função que se auto executa, então toda vez que atualizar a página ela executara a função Pesquisa, e como o usuário não digitou alguma valor para a busca ela chegará na nossa API com um parâmetro nulo.
E como tratamos caso a variável do parâmetro for nula ela devolvera todos os funcionários.
Relembrando o código responsável por devolver a pesquisa.


        public ListGet(string pesquisa)
        {
            var cliente = new List()
            {
                new Funcionario {codigo =1,nome="Juliano Sales",email="juliano.salesg@gmail.com",cargo="Desenvolvedor"},
                new Funcionario {codigo =2,nome="Bruno",email="bruno@gmail.com",cargo="Gerente de Projeto"},
                new Funcionario {codigo =3,nome="Fernanda",email="fernanda@gmail.com",cargo="Gerente de RH"},
                new Funcionario {codigo =4,nome="Lucas",email="lucas@gmail.com",cargo="Gerente Administrativo"}
            };

            if (pesquisa != null && pesquisa !="")
                return cliente.Where(l => l.nome.ToUpper().Contains(pesquisa.ToUpper())).ToList();
            else
                return cliente;
        }

E no final do nosso script nos temos o código responsável por unir nossa interface com nosso objeto ko.applyBindings(viewModelFuncionario);
Depois de explicar um pouco de como funciona nosso script, creio que ficou fácil de entender a utilização do foreach dentro do html, simplesmente ele está percorrendo o nosso objeto ListaFuncionario

Aprendemos nesse post como mapear nosso modelo de dados com a nossa UI, até o próximo post sobre Knockout .

12 Responses so far.

  1. Verdade disse:
    Impressionante como podem apoiar essas soluções gambiarras. Já viram como é fazer um if???
  2. Juliano Sales disse:
    Sinceramente gosto muito da arquitetura do Knockout js, creio que logo ele estará ainda melhor quando o desenvolvimento em SPA for cada vez mais forte.Gostaria muito que você apontasse as partes ruim da biblioteca. O brigado por deixar o seu comentário.
  3. Verdade disse:
    Oi, como posso fazer um if decente e de forma clássica em algum desses frameworks JS como por exemplo o ko?
  4. Verdade disse:
    Como fazemos server side via Razor por exemplo. Jogar a logica pro JS???
  5. Juliano Sales disse:
    Olá amigo tudo bem, desculpa pela demora, no seu JS não ficara nenhuma lógica do domínio, as libs ajudam você integrar o dados exposto com a sua interface.
    Uma vantagem de expor dados no formato de json , xml …. e que cada aplicativo pode consumir e usar os dados de acordo com a sua necessidade.
    Recentemente fiz um projeto utilizando esse conceito a performasse e o reaproveitamento foi incrível.
    E sobre o outro comentário do if no knockout também não me agrada muito, porém aprendi muita coisa com a arquitetura do knockout e criei minha própria arquitetura.Tem outro framework chamado backbone js e ele e muito interessante.
  6. Juliano Sales disse:
    Obrigado pelo comentário e desculpa pela demora, nesse momento não tenho porém logo irei postar.
  7. Rodrigo disse:
    Bacana o knockout…hoje há inúmeros frameworks para spa, estou a começar um projeto spa, mas ainda estou na dúvida entre qual deles usar…rsrsrs até por que, existe vários não?
    AngularJs, EmberJs,Knockout,BackBoneJs(como você citou)
    Mas estou bem tendencioso a usar knockout ou Angular, O que você acha?
    Abraço, ótimo post :-)
  8. Juliano Sales disse:
    Muito obrigado pelo comentário fico feliz que tenha gostado, eu também fiquei com muitas duvidas em qual utilizar, eu gostei bastante do knockout JS e do Backbone JS hoje eu prefiro mais o Backbone porque eu posso trabalhar com mais liberdade e com essa liberdade você tem que escrever mais código, vou te passar dois links legais para você tirar a sua própria conclusão http://todomvc.com/ , http://www.mvcsummit.com.br/ -> no canal do You Tube você vai encontrar a primeira parte do encontro onde abordaram sobre Knockout JS ,Backone JS, Angular JS. Até mais.
  9. Rodrigo disse:
    Usando KnockoutJS nós eliminamos o uso de html helpers? exemplo

    @Html.DisplayNameFor(model => model.Title)

    @Html.DisplayFor(model => model.Title)

    Usando ferramentas como o knockoutjs não utilizamos mais esses helpers?
    Alias, em app spa, não utilizamos mais os helpers? rs

  10. Juliano Sales disse:
    Olá Rodrigo,
    Quando utilizamos uma arquitetura SPA o foco é no cliente ou seja fazemos uma requisição no servidor através do java script e com o retorno do servidor pegamos os dados e trabalhamos com ele . A ideia do SPA e deixar o Server Side magrinho ou seja nada de gerar HTML no lado do servidor apenas retornar dados.
    Espero que tenha conseguido responder sua pergunta. Abraço e fica com Deus.
  11. Rodrigo disse:
    Entendi sim Juliano, obrigado pela resposta..
    Em relação a isso, deixar o Server Side magrinho, rs
    Eu utilizo os helpers apenas na minha view Editar, achei melhor para carregar já os dados nos inputs
    hehehe
    Só nas view de edição mesmo, nas demais, não utilizo helpers html
    Abraço
  12. Verdade disse:
    Rodrigo, cuidado para não usar isso em casos que não sejam adequados. Se você está fazendo um site ou sistema web clássico pode ser desperdício, pois terá sempre uma requisição do HTML e outra para os dados e não uma só com o HTML e os dados já processados. Utilize isso somente em WebApps onde os HTMLs já estarão instalados no dispositivo do usuário.

LEAVE A COMMENT