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.
A tela é divida em três partes:
- Na primeira parte é exibido um formulário onde você pode digitar dados de contato e clicar em adicionar
- 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.
- 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: <labelfor="nome">Nome</label>
4: <inputid="nome"name="nome"type="text"data-bind="value:Nome"/><br/>
5: <labelfor="telefone">Telefone</label>
6: <inputid="telefone"name="telefone"type="text"data-bind="value:Telefone"/><br/>
7: <labelfor="email">E-mail</label>
8: <inputid="email"type="email"name="email"data-bind="value:Email"/><br/>
9: <inputtype="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: <tbodydata-bind="foreach: Contatos">
19: <tr>
21: <td><inputtype="text"data-bind="value:Telefone"/></td>
22: <td><inputtype="text"data-bind="value:Email"/></td>
23: <td><ahref='#'data-bind='click: MeuModelo.removerContato'>Remover</a></td>
24: </tr>
25: </tbody>
26: </table>
27: <inputtype="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.
Também vou adicionar a referência para o Jquery e para a biblioteca do KnockoutJS que acabamos de instalar:
<scripttype="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: publicclass Contato
4: {
5: publicstring Nome { get; set; }
6: publicstring Telefone { get; set; }
7: publicstring 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.
É isso pessoal. Por hoje era isso.
Até o próximo.
Fonte do Projeto: