Asp.Net MVC - Enviando dados para o servidor com KnockoutJS e JQuery    

Olá pessoal.

Já faz um tempo que falei de KnockoutJS. Hoje vou falar mais uma vez para tirar uma dúvida recorrente aqui no blog: Como enviar dados do meu modelo KnockoutJS para uma Action do MVC.

Vou fazer um exemplo simples e objetivo. Como o título do post diz, a ideia é mostrar apenas o envio dos dados para o servidor, como obter do servidor não será abordado (quem sabe em outro post).

Vamos explicar como será a aplicação na imagem abaixo:

Imagem 1 – Tela de cadastro.

Imagem 1 – Tela de cadastro.

A tela é divida em três partes:

  1. Na primeira parte é exibido um formulário onde você pode digitar dados de contato e clicar em adicionar
  2. Na segunda parte são exibidos os contatos já adicionados. Você pode clicar no link Remover no final de cada linha para remover o item já adicionado.
  3. Na terceira parte você pode clicar no botão Salvar. Apenas após clicar nesse botão seus dados adicionados a lista serão enviados para o servidor.

A aplicação é bem simples, mas é o suficiente para mostra como enviar dados do JavaScript para o servidor.

Vamos agora ver como a tela foi feita.

   1:  <h3>Cadastro:</h3>
   2:   
   3:  <label for="nome">Nome</label>
   4:  <input id="nome" name="nome" type="text" data-bind="value:Nome" /><br />
   5:  <label for="telefone">Telefone</label>
   6:  <input id="telefone" name="telefone" type="text" data-bind="value:Telefone" /><br />
   7:  <label for="email">E-mail</label>
   8:  <input id="email" type="email" name="email" data-bind="value:Email" /><br />
   9:  <input type="button" data-bind="click:adicionarContato" value="Adicionar >>" />
  10:   
  11:  <table>
  12:      <thead>
  13:          <th>Nome</th>
  14:          <th>Telefone</th>
  15:          <th>E-mail</th>
  16:          <th></th>
  17:      </thead>
  18:      <tbody data-bind="foreach: Contatos">
  19:          <tr>


  21:              <td><input type="text" data-bind="value:Telefone" /></td>
  22:              <td><input type="text" data-bind="value:Email" /></td>
  23:              <td><a href='#' data-bind='click: MeuModelo.removerContato'>Remover</a></td>
  24:          </tr>
  25:      </tbody>
  26:  </table>
  27:  <input type="button" value="Salvar" data-bind="click:salvarContato" />

Esse é todo o HTML utilizado para fazer a tela acima. Da 1 à 9 crio o formulário para adicionar contatos. Da linha 11 à 26 crio a tabela que é exibido os registros adicionados, e por fim na linha 27 adiciono o botão para salvar no servidor.

Repare que em todos os campos estou adicionando o atributo data-bind do KnockoutJS. Para os botões informo que vou utilizar o evento click para invocar o respectivo método do meu modelo (abaixo). Para os campos (input) informo no data-bind que desejo que o atributo value seja preenchido  com o respectivo valor.

Para utilizar o KnockoutJS, posso fazer o download direto no site http://knockoutjs.com ou apenas utilizar o Nuget. No meu caso vou utilizar o Nuget com o comando abaixo no Visual Studio:

PM> Install-Package knockoutjs

Uma vez executado, todos os arquivos necessários para utilizar o Knockout estarão na pasta de Scripts do meu site:

Imagem 2 – Scripts do Site

Imagem 2 – Scripts do Site.

Também vou adicionar a referência para o Jquery e para a biblioteca do KnockoutJS que acabamos de instalar:

<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Scripts/knockout-2.2.1.js")"></script>

Agora vamos ao JavaScript necessário para fazer minha aplicação funcionar:

   1:  <script type="text/javascript">
   2:  var MeuModelo = {
   3:      Nome: ko.observable(),
   4:      Telefone: ko.observable(),
   5:      Email: ko.observable(),
   6:      Contatos: ko.observableArray([]),
   7:      adicionarContato: function () {
   8:          this.Contatos.push({ Nome: this.Nome(), Telefone: this.Telefone(), Email: this.Email() })
   9:          this.Nome("");
  10:          this.Telefone("");
  11:          this.Email("");
  12:      }
  13:      , removerContato: function (contato) {
  14:          MeuModelo.Contatos.remove(contato);
  15:      }
  16:      , salvarContato: function () {
  17:          var dados = ko.toJS(MeuModelo.Contatos);
  18:          $.ajax({
  19:              type: "POST",
  20:              contentType: "application/json",
  21:              url: "Home/SalvarContato",
  22:              data: JSON.stringify({ contatos: dados }),
  23:              traditional: true,
  24:              success: MeuModelo.sucesso,
  25:              error: MeuModelo.falha
  26:          });
  27:      }
  28:      ,sucesso: function () { alert("Sucesso");}
  29:      ,falha: function () { alert("Falha"); }
  30:   
  31:      };
  32:   
  33:  ko.applyBindings(MeuModelo);
  34:  </script>

No JavaScript acima estou criando um ViewModel, ou seja, um modelo para gerenciar minha View. Vamos explicar linha por linha:

  • Da linha 3 a 5 estou criando as propriedades observáveis para os três campos do formulário que adiciona os contatos.
  • Na linha 6 estou criando o Array observável que conterá os registros da lista da tela.
  • Entre as linhas 7 e 12 crio o método que será chamado quando for clicado no botão Adicionar. Esse método adiciona os valores atuais das propriedades criadas entre as linhas 3 e 5 ao Array Contatos. Uma vez que o Array muda no JavaScript, a tela atualiza automaticamente. Esse é o KnockoutJS em ação. Para finalizar o método, entre as linhas 9 e 11 eu limpo os campos onde os valores foram digitados.
  • Entre as linhas 13 e 15 eu implemento o método responsável por remover um item do array e atualizar a tela quando clicado no link Remover na lista.
  • Entre as linhas 16 e 29 eu crio o método responsável por enviar os dados ao Servidor. Primeiramente, na linha 17 eu transforme o meu Array observável em um Array puro de JavaScript utilizando o método do KnockoutJS chamado ko.toJS. Em seguida invoco o método ajax do JQuery, invocando o método POST e definido que o conteúdo será do tipo “application/json”. Para enviar os dados ao servidor, eu transformo meus dados em uma string JSON, encapsulando o Array em um campo com o mesmo nome do parâmetro da Action. (Linha 22)
  • Por fim, na linha 33 eu aplico o Binding entre o meu modelo JavaScript e a minha página HTML.

Agora, por último, devemos ver como criar a Action em meu Controller MVC.

É bem simples. Primeiro crio um ViewModel de Contato em meu C#, e em seguida crio uma Action que recebe um um array desse ViewModel:

   1:  namespace Mvc_Knockout.Models
   2:  {
   3:      public class Contato
   4:      {
   5:          public string Nome { get; set; }
   6:          public string Telefone { get; set; }
   7:          public string Email { get; set; }
   8:      }
   9:  }

E a Action:

   1:  [AcceptVerbs(HttpVerbs.Post)]
   2:  public JsonResult SalvarContato(Contato[] contatos)
   3:  {
   4:      foreach (var contato in contatos)
   5:      {
   6:          //Lógica para salvar
   7:      }
   8:      return Json(contatos);
   9:  }

Informo que minha Action receberá um Post, e não um simples Get, pois informei na chamada Ajax que enviaria um Post. Uma vez que os dados estiverem no servidor, você pode utilizar a lógica e ferramenta que achar melhor para persistir, como NHibernate ou Entity Framework.

Veja abaixo o print dos meus dados no servidor após clicar no botão Salvar. (Os mesmos dados que estão na tela da imagem da tela (Imagem 1))

 

Imagem 3 – Dados no Servidor.

Imagem 3 – Dados no Servidor.

É isso pessoal. Por hoje era isso.

Até o próximo.

Fonte do Projeto:

Mvc+Knockout.zip (3,01 mb)

18. fevereiro 2013 23:57 by Frederico B. Emídio | Comments (1) | Permalink

Sobre mim

Minha Imagem

Meu nome é Frederico Batista Emídio, trabalho com desenvolvimento de sistemas profissionalmente a oito anos, porém, já faço sites pessoais a pelo menos dez anos.

Para saber mais clique aqui.

Páginas

Calendário

<<  novembro 2017  >>
seteququsedo
303112345
6789101112
13141516171819
20212223242526
27282930123
45678910

Visualizar posts em um Calendário
Sigua @fredemidio

MCP Asp.NET