.NET - Usando o Knockout (KO) com ASP .NET MVC


Você conhece o Knockout (KO) ?

Na definição oficial - http://knockoutjs.com/ o Knockout é uma biblioteca JavaScript (Open Source) que simplifica a construção de interfaces gráficas dinâmicas, usando o padrão MVVM. (Model-View-ViewModel)

Estruturalmente, uma aplicação que usa o padrão MVVM consiste basicamente em três componentes principais: o Modelo, a Visão(View) e a ViewModel.
    O Model ou modelo é a entidade que representa o conceito do negócio, que pode ser desde uma simples entidade de cliente para uma entidade complexa de ações comerciais;
    A View ou Visão é o controle gráfico ou um conjunto de controles responsáveis pela apresentação do modelo de dados ao usuário. Uma visão pode ser uma janela WPF, uma 
página do Silverlight, ou apenas um modelo de controle de dados XAML.
    O ViewModel - É realmente quem faz a diferença; O ViewModel contém a lógica de interface do usuário, os comandos, os eventos, e uma referência para o modelo. Na MVVM, 
o ViewModel não é responsável por atualizar os dados exibidos na interface do usuário graças ao poderoso motor de vinculação de dados fornecidos pelo WPF e Silverlight, a 
ViewModel não precisa fazer isso. Como o View é um observador do ViewModel, tão logo o ViewModel sofra mudanças, a Interface do Usuário se atualiza de forma automática. 
Para que isso ocorre a ViewModel tem que implementar a interface INotifyPropertyChanged e acionar o evento PropertyChanged.

Dessa forma a Knockout (KO) é uma biblioteca JavaScript que o ajuda a criar interfaces ricas com um correspondente modelo de dados.

A seguir temos alguns dos recursos presentes na Knockout :

Você pode baixar o KnockoutJS neste link: http://knockoutjs.com/downloads/index.html

Existe um tutorial on-line rápido que pode ser acessado neste link: http://learn.knockoutjs.com/

Padrão Model-View-ViewModel - MVVM

O padrão MVVM é uma evolução do PM que tem os três componentes :

No padrão MVVM temos que :

  1. - informação vem do Modelo e vai para o ViewModel;
  2. - quando a informação do ViewModel é atualizada ela volta ao Modelo;
  3. - quando a informação do ViewModel é atualizada a View é automaticamente atualizada;
  4. - quando a informação da View é alterada o ViewModel é automaticamente atualizado;

Por estes motivos a biblioteca Knockout (KO) pode ser usada para criar interfaces mais dinâmicas.

Mas e o jQuery ???

A jQuery também é uma biblioteca JavaScript (Open Source) muito usada em aplicações ASP .NET que tem um mecanismo forte de vinculação de dados que usa ids de tags HTML, uma classe CSS e um nome de tag HTML. Os valores são enviados do objeto de origem para os elementos HTML, exigindo assim uma linha de código para cada mapeamento do valor de origem para o elemento de destino. jQuery é simples de se vincular com os valores e tags.

Mas tem um problema...

E neste cenário é que entra o KO visto que sua proposta é justamente realizar estas operações usando o padrão MVVM.

Assim o KO não é uma alternativa para bibliotecas jQuery ou outras bibliotecas JavaScript (Prototype, MooTools). O foco da KO esta no padrão MVVM usado para manipular o Model para a View a partir de chamadas AJAX. A KO realiza o gerenciamento entre o ViewModel e a View e a relação automática que é acionada a partir de chamadas de interface de usuário.

Dessa forma o KO usa os seguintes conceitos:

Vejamos um exemplo bem básico de utilização da biblioteca knockout. Após baixar o arquivo JavaScript do site e nomeá-lo como knockout-2.2.1.js vamos abrir o bloco de dados e digitar o código abaixo:

<h2>Usando Knockout</h2>
<span> Código do Aluno:</span><span data-bind="text: Numero"></span>
<br/>
<span>Sobrenome:</span><input
data-bind="value: Sobrenome"/>
<span>Nome:</span><input
data-bind="value: Nome"/>
<script type='text/javascript' src='knockout-2.2.1.js'></script>
<script type="text/javascript">
var aluno= {
        Numero: "A003456",
        Sobrenome: "Macoratti",
        Nome: "Jose Carlos"
    }
      
 // ativa knockout.js
    ko.applyBindings(aluno);

</script>

A referência a biblioteca é feita na linha : <script type='text/javascript' src='knockout-2.2.1.js'></script>

Você deve atualizar o atributo src indicando o caminho onde o arquivo javascript referente à biblioteca Knockout estiver localizado.

A tag HTML de vinculação não esta apta para observar a estrutura de vinculação de dados.

A biblioteca KO se concentra na vinculação de dados usando a tag data-bind que vincula os dados aos elementos HTML da interface.

Abrindo a página em um navegador teremos o seguinte resultado:

Mas existe uma outra sintaxe de pode ser usada para controlar as alterações da View para os valores do modelo de objetos.

Nesta sintaxe a propriedade Observable é muito importante pois o padrão MMVM precisa observar qualquer alteração na interface e dessa forma a KO irá considerar qualquer mudança na View.

Quando editarmos uma das caixas de texto os dados relacionados no ViewModel será atualizado.

Vamos alterar o código conforme mostrado a seguir:

<h2>Usando Knockout</h2>
<span> Código do Aluno:</span><span data-bind="text: Numero"></span>
<br/>
<span>Sobrenome:</span><input data-bind="value: Sobrenome"/>
<span>Nome:</span><input data-bind="value: Nome"/>
<script type='text/javascript' src='knockout-2.2.1.js'></script>
<script type="text/javascript">
var aluno= {
        Numero: ko.observable("A003456"),
        Sobrenome: ko.observable("Macoratti"),
        Nome: ko.observable("Jose Carlos")

    }
        // ativa knockout.js
    ko.applyBindings(aluno);
</script>

Atualizamos o ViewModel para tornar as propriedades Nome e Sobrenome observáveis usando ko.observable.

Executando novamente o arquivo html e editando as caixas de texto veremos não somente os dados do ViewModel serem atualizados mas toda a interface associada é atualizada em sincronia.

Podemos utilizar valores calculados e adicionar outros comportamentos usando os recursos da API Knockout.

Vamos continuar agora mostrando como usar a biblioteca em uma aplicação ASP .NET MVC. Neste artigo abordarei os seguintes recursos do Knockout:

O exemplo irá utilizar os seguintes tipos de vinculação:

Criando uma aplicação ASP .NET MVC 4 com Knockout e Entity Framework -

Aplicações do mundo real quase sempre precisam ser alimentadas a partir de um banco de dados.

Assim, o model seria os dados armazenados da sua aplicação que deveriam ser implementadas usando uma tecnologia do lado do servidor.

A View esta interessada nos pedidos de interface - UI e o ViewModel contém objetos para gerenciar quaisquer respostas a partir da View.

Vamos abrir o Visual Studio Express 2012 for web e no menu FILE clicar em New Project;

Selecione o template Visual C# -> Web -> ASP .NET MVC 4 Web Application e informe o nome UsandoKnockout e clique no botão OK;

A seguir selecione o template Internet Application e o engine Razor e clique no botão OK;

Ao final termos um projeto ASP .NET MVC criado com toda a estrutura pronta para ser usada.

Vamos a estrutura criada no projeto MVC para definir o nosso modelo, controlador e Views sem nos importamos com a estrutura original criada fazendo apenas alguns ajustes necessários.

Definindo o Banco de dados e os scripts Knockout

No projeto criado a pasta Scripts já ira conter o arquivo knockout-2.1.0.js mas vamos incluir a versão knockout-2.2.1.js atualizada na pasta Scripts.

Clique com o botão direito do mouse na pasta Scripts e selecione Add - Existing Item;

Selecione o arquivo knockout-2.2.1 partir do local onde você o baixou.

Repita o procedimento e inclua também o arquivo knockout.mapping-latest.js que você pode baixar neste link: http://knockoutjs.com/documentation/plugins-mapping.html

Vamos agora definir o banco de dados usado em nosso exemplo.

Clique no menu VIEW e a seguir em DataBase Explorer para visualizar as conexões disponíveis.

A seguir clique com o botão direito do mouse sobre o item Data Connections e a seguir em Add Connection;

Na janela Add Connection informe o nome do servidor local SQL Server : .\sqlexpress e selecione o banco de dados com o qual deseja trabalhar:

Em nosso exemplo irei usar o banco de dados Cadastro.mdf e a tabela Funcionarios que possui a seguinte estrutura:

Definindo o Model

Vamos definir o Model da nossa aplicação iniciando com a criação de um Entity Data Model na pasta Models.

Clique com o botão direito do mouse sobre a pasta Models e a seguir em Add - New Item;

Selecione o template ADO .NET Entity Data Model e informe o no me Funcionarios.edmx e clique em Add;

Em seguida clique na opção : Generate from database e clique em Next>;

Selecione a conexão com o banco de dados desejado, aceite os nomes padrões sugeridos e clique em Next>;

Selecione a tabela com a qual deseja trabalhar, no nosso exemplo a tabela Funcionarios. Aceite o nome padrão e clique em Finish;

Ao final teremos o EDM gerado para a tabela Funcionarios conforme mostra a figura abaixo:

Realize um Build no projeto clicando no menu BUILD -> Build Solution.

Criando o controlador

Clique com o botão direito do mouse sobre a pasta Cotnrollers e a seguir em Add -> Controller;

A seguir informe o nome FuncionarioController e selecione as seguinte opções conforme mostra a figura e clique no botão Add;

Vamos utilizar os métodos HTTP GET, POST, PUT e DELETE com os quais poderemos requisitar usando métodos Ajax fornecidos na biblioteca jQuery de forma assíncrona.

Vamos criar outro controlador na pasta Controllers repetindo o processo acima informando o nome FunciController e selecionando o template Empty MVC Controller;

Neste controlador vamos criar o método Create conforme mostrado abaixo:

 public ActionResult Create()
 {
     return View("Create");
 }

Definindo a View

Vamos agora definir a view para o controlador FunciController que criamos por último na pasta Controllers.

Para isso selecione o método Create no controlador e clique no seu interior com o botão direito do mouse e a seguir clique em Add View;

Na janela Add View informe aceite o nome Create para a View e clique no botão Add;

Dessa forma iremos criar uma view vazia na pasta /Views/Funci.

Vamos agora definir o código desta view com os recursos do Knockout.

Iniciamos definindo as referências às bibliotecas jQuery e Knockout:

@{
    ViewBag.Title = "Create";
}

<h2>Create</h2>

<head>
    <script src="~/Scripts/jquery-1.7.1.js"></script>
    <script src="~/Scripts/knockout-2.2.1.js"></script>
    <script src="~/Scripts/knockout.mapping-latest.js"></script>
    <link href="~/Content/Site.css" rel="stylesheet" />
</head>

Agora vamos definir o código destacado em azul abaixo no arquivo Create.cshtml de forma a criar uma interface para exibição dos dados dos funcionários permitindo as operações de atualização e exclusão :

@{
    ViewBag.Title = "Create";
}

<h2>Cadastro</h2>

<head>
    <script src="~/Scripts/jquery-1.7.1.js"></script>
    <script src="~/Scripts/knockout-2.2.1.js"></script> 
    <script src="~/Scripts/knockout.mapping-latest.js"></script>
    <link href="~/Content/Site.css" rel="stylesheet" />
</head>

<form>
<table>
  <tr>
   <td>
   <!-- Vincula os TextBoxes na tabela para as propriedades observable definidas no ViewModel -->
    <table id="tbldml">
     <tr>
      <td>ID</td>
      <td><input type="text" id="txtid" disabled="disabled" /></td>
     </tr>
    <tr>
     <td>Nome</td>
     <td><input type="text" id="txtnome" /></td>
    </tr>
    <tr>
     <td>Titulo</td>
     <td><input type="text" id="txttitulo" /></td>
    </tr>
    <tr>
     <td>Nascimento</td>
     <td><input type="text" id="txtnascimento" /></td>
     </tr>
     <tr>
     <td>Estado Civil</td>
     <td><input type="text" id="txtestadocivil" /></td>
     </tr>
      <tr>
     <td>Sexo</td>
     <td><input type="text" id="txtsexo" /></td>
     </tr>
     <tr>
      <td>Admissão</td>
      <td><input type="text" id="txtadmissao" /></td>
      </tr>
       <tr>
       <!-- A vinculacao click possui os métodos JavaScirpt passados-->
        <td><button>Salvar</button></td>
        <td><button>Atualizar</button></td>
        </tr>
       </table>
      </td>
      <td>
       <div class="FixedContainer">
        <table style="border: double">
         <thead>
          <tr>
          <td>ID</td>
          <td>Nome</td>
          <td>Titulo</td>
          <td>Nascimento</td>
          <td>Estado Civil</td>
          <td>Sexo</td>
          <td>Admissão</td>
          <td></td>
         </tr>
        </thead>
        <!--Itera através de um observableArray usando foreach-->
        <tbody>
         <tr style="border: solid">
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><button >Deletar</button></td>
         </tr>
        </tbody>
       </table>
      </div>
     </td>
    </tr>
   </table>
  </form>

Antes de executar o projeto temos que realizar dois ajustes:

1- Abra o arquivo Site.css na pasta Content e inclua o estilo definido abaixo:

.FixedContainer
{
  float:right;
  height: 250px;
  width:500px;
  padding:3px;
   overflow:auto;
}

.FixedContent
{
  height:224px;
   overflow:auto;
}

2- Abra o arquivo _Layout.chstml da pasta Shared e alterar o código para permitir a navegação até a nossa view Create.chstml:

   ...
              <nav>
                        <ul id="menu">
                            <li>@Html.ActionLink("Home", "Index", "Home")</li>
                            <li>@Html.ActionLink("About", "About", "Home")</li>
                            <li>@Html.ActionLink("Funcionarios", "Create", "Funci")</li>
                        </ul>
                    </nav>
    ...

Removi a referência a Contact e inclui a linha para permitir a navegação pela view Create na pasta Funci.

Obs: realizei outros ajutes nos arquivos Index.cshtml, about.cshtml, _LoginPartial.cshtml e HomeController.cs de forma tornar a interface mais simples.

Executando o projeto iremos obter a página principal conforme abaixo:

Clicando no menu Funcionarios teremos a seguinte página exibindo a interface que definimos no arquivo Create.cshtml:

Temos que completar o código para implementar as operações para Salvar, Atualizar, Selecionar dados e Deletar informações. Vamos então incluir o código destacado em azul no arquivo Create.cshtml:

@{
    ViewBag.Title = "Create";
}
<html>

<h2>Cadastro</h2>

<head>
    <script src="~/Scripts/jquery-1.7.1.js"></script>
    <script src="~/Scripts/knockout-2.2.1.js"></script> 
    <script src="~/Scripts/knockout.mapping-latest.js"></script>
    <link href="~/Content/Site.css" rel="stylesheet" />
</head>
<body>
 <form>
  <table>
  <tr>
   <td>
   <!-- Vincula os TextBoxes na tabela para as propriedades observable definidas no ViewModel -->
    <table id="tbldml">
     <tr>
      <td>ID</td>
      <td><input type="text" id="txtid" disabled="disabled" /></td>
     </tr>
    <tr>
     <td>Nome</td>
     <td><input type="text" id="txtnome" /></td>
    </tr>
    <tr>
     <td>Titulo</td>
     <td><input type="text" id="txttitulo" /></td>
    </tr>
    <tr>
     <td>Nascimento</td>
     <td><input type="text" id="txtnascimento" /></td>
     </tr>
     <tr>
     <td>Estado Civil</td>
     <td><input type="text" id="txtestadocivil" /></td>
     </tr>
      <tr>
     <td>Sexo</td>
     <td><input type="text" id="txtsexo" /></td>
     </tr>
     <tr>
      <td>Admissão</td>
      <td><input type="text" id="txtadmissao" /></td>
      </tr>
       <tr>
       <!-- A vinculacao click possui os métodos JavaScirpt passados-->
        <td><button>Salvar</button></td>
        <td><button>Atualizar</button></td>
        </tr>
       </table>
      </td>
      <td>
       <div class="FixedContainer">
        <table style="border: double">
         <thead>
          <tr>
          <td>ID</td>
          <td>Nome</td>
          <td>Titulo</td>
          <td>Nascimento</td>
          <td>Estado Civil</td>
          <td>Sexo</td>
          <td>Admissão</td>
          <td></td>
         </tr>
        </thead>
        <!--Itera através de um observableArray usando foreach-->
        <tbody>
         <tr style="border: solid">
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><span></span></td>
          <td><button >Deletar</button></td>
         </tr>
        </tbody>
       </table>
      </div>
     </td>
    </tr>
   </table>
  </form>
 <script type="text/javascript">
        var FunciViewModel = function () {
            var self = this;
            //Declara um observable o qual se vinculará a Interface - UI 
            self.funcionarioid = ko.observable("0");
            self.Nome = ko.observable("");
            self.Titulo = ko.observable("");
            self.Nascimento = ko.observable("");
            self.EstadoCivil = ko.observable("");
            self.Sexo = ko.observable("");
            self.Admissao = ko.observable("");

            //Objeto que armazena os dados entrados nos observables
            var FunciDados = {
                funcionarioid: self.funcionarioid,
                Nome: self.Nome,
                Titulo: self.Titulo,
                Nascimento: self.Nascimento,
                EstadoCivil: self.EstadoCivil,
                Sexo: self.Sexo,
                Admissao: self.Admissao
            };

            //Declara um ObservableArray para armazenar a reposta  JSON
            self.Funcionarios = ko.observableArray([]);

            GetFuncionarios(); //Chama a função que pega os registros usando uma chamada Ajax

            //Função para raealizar o POSt
            self.save = function () {
                //Chamada Ajax para inserir um funcionario
                $.ajax({
                    type: "POST",
                    url: "/api/Funcionario",
                    data: ko.toJSON(FunciDados), //Converte os dados Observable para JSON
                    contentType: "application/json",
                    success: function (data) {
                        alert("Registro incluído com sucesso");
                        self.funcionarioid(data.funcionarioid);
                        alert("O novo ID do Funcionário :" + self.funcionarioid());
                        GetFuncionarios();
                    },
                    error: function () {
                        alert("Falhou");
                    }
                });
                //fim
            };

            self.update = function () {
                var url = "/api/Funcionario/" + self.funcionarioid();
                alert(url);
                $.ajax({
                    type: "PUT",
                    url: url,
                    data: ko.toJSON(FunciDados),
                    contentType: "application/json",
                    success: function (data) {
                        alert("Registro atualizado com sucesso.");
                        GetFuncionarios();
                    },
                    error: function (error) {
                        alert(error.status + "<!----!>" + error.statusText);
                    }
                });
            };

            //Função para realizar a operação de DELETE
            self.deleterec = function (_funcionario) {
                $.ajax({
                    type: "DELETE",
                    url: "/api/Funcionario/" + _funcionario.funcionarioid,
                    success: function (data) {
                        alert("Registro deletado com sucesso");
                        GetFuncionarios();//Refresh the Table
                    },
                    error: function (error) {
                        alert(error.status + "<--and--> " + error.statusText);
                    }
                });
                alert("Selecionado :" + _funcionario.funcionarioid)
            };

            //Função para ler todos os  Funcionarios
            function GetFuncionarios() {
                // chamara Ajax para pegar todos os funcionarios
                $.ajax({
                    type: "GET",
                    url: "/api/Funcionario",
                    contentType: "application/json; charset=utf-8",
                    dataType: "json",
                    success: function (data) {
                        self.Funcionarios(data); //Poe a resposta no ObservableArray
                    },
                    error: function (error) {
                        alert(error.status + "<--and--> " + error.statusText);
                    }
                });
                //fim
            }

            //Função para exibir o registro atualizado
            self.getselected_funcionario = function (_funcionario) {
                self.ID(_funcionario.ID),
                self.Nome(_funcionario.Nome),
                self.Titulo(_funcionario.Titulo),
                self.Nascimento(_funcionario.Nascimento),
                self.EstadoCivil(_funcionario.EstadoCivil),
                self.Sexo(_funcionario.Sexo),
                self.Admissao(_funcionario.Admissao)
            };
        };
        ko.applyBindings(new FunciViewModel());
    </script>
</body>
</html>

Vamos destacar os pontos principais deste código:

Ainda sim, temos que vincular os textbox da interface do usuário com o observable definido no ViewModel bem como as funções definidas no ViewModel que deverão ser vinculadas as botões de comando. A vinculação é feita usando o atributo 'data-bind'.

Vamos então alterar o código HTML do arquivo create.cshtml com o código a seguir:

  @{
    ViewBag.Title = "Create";
}
<html>
<h2>Create</h2>
<head>
    <script src="~/Scripts/jquery-1.8.2.js"></script>
    <script src="~/Scripts/knockout-2.2.0.js"></script> 
    <script src="~/Scripts/knockout.mapping-latest.js"></script>
    <link href="~/Content/Site.css" rel="stylesheet" />
</head>
<body>
 <form>
  <table>
  <tr>
   <td>
   <!-- Vincula os TextBoxes na tabela para as propriedades observable definidas no ViewModel -->
    <table id="tbldml">
     <tr>
      <td>ID</td>
      <td><input type="text" id="txtid" data-bind="value: funcionarioid" disabled="disabled" /></td>
     </tr>
    <tr>
     <td>Nome</td>
     <td><input type="text" id="txtnome" data-bind="value: nome" /></td>
    </tr>
    <tr>
     <td>Titulo</td>
     <td><input type="text" id="txttitulo" data-bind="value: titulo" /></td>
    </tr>
    <tr>
     <td>Nascimento</td>
     <td><input type="text" id="txtnascimento" data-bind="value: nascimento" /></td>
     </tr>
     <tr>
     <td>Estado Civil</td>
     <td><input type="text" id="txtestadocivil" data-bind="value: estadocivil" /></td>
     </tr>
      <tr>
     <td>Sexo</td>
     <td><input type="text" id="txtsexo" data-bind="value: sexo" /></td>
     </tr>
     <tr>
      <td>Admissão</td>
      <td><input type="text" id="txtadmissao" data-bind="value: admissao" /></td>
      </tr>
       <tr>
       <!-- A vinculacao click possui os métodos JavaScirpt passados-->
        <td><button data-bind="click: save">Salvar</button></td>
        <td><button data-bind="click: update">Atualizar</button></td>
        </tr>
       </table>
      </td>
      <td>
       <div class="FixedContainer">
        <table data-bind="visible: Funcionarios().length>0" style="border: double">
         <thead>
          <tr>
          <td>ID</td>
          <td>Nome</td>
          <td>Titulo</td>
          <td>Nascimento</td>
          <td>Estado Civil</td>
          <td>Sexo</td>
          <td>Admissão</td>
          <td></td>
         </tr>
        </thead>
        <!--Itera através de um observableArray usando foreach-->
        <tbody data-bind="foreach:  Funcionarios">
         <tr style="border: solid" data-bind="click: getfuncionarioselecionado" id="updtr">
          <td><span data-bind="text: funcionarioid"></span></td>
          <td><span data-bind="text: nome"></span></td>
          <td><span data-bind="text: titulo"></span></td>
          <td><span data-bind="text: nascimento"></span></td>
          <td><span data-bind="text: estadocivil"></span></td>
          <td><span data-bind="text: sexo"></span></td>
          <td><span data-bind="text: admissao"></span></td>
          <td><button data-bind="click: delete">Deletar</button></td>
         </tr>
        </tbody>
       </table>
      </div>
     </td>
    </tr>
   </table>
  </form>
 <script type="text/javascript">

     var FunciViewModel = function () {
         var self = this;
         //Declara um observable o qual se vinculará a Interface - UI 
         self.funcionarioid = ko.observable("0");
         self.nome = ko.observable("");
         self.titulo = ko.observable("");
         self.nascimento = ko.observable("");
         self.estadocivil = ko.observable("");
         self.sexo = ko.observable("");
         self.admissao = ko.observable("");

         //Objeto que armazena os dados entrados nos observables
         var FunciDados = {
             funcionarioid: self.funcionarioid,
             Nome: self.nome,
             Titulo: self.titulo,
             Nascimento: self.nascimento,
             EstadoCivil: self.estadocivil,
             Sexo: self.sexo,
             Admissao: self.admissao
         };

         //Declara um ObservableArray para armazenar a reposta  JSON
         self.Funcionarios = ko.observableArray([]);

         GetFuncionarios(); //Chama a função que pega os registros usando uma chamada Ajax

         //Função para raealizar o POSt
         self.save = function () {
             //Chamada Ajax para inserir um funcionario
             $.ajax({
                 type: "POST",
                 url: "/api/Funcionario",
                 data: ko.toJSON(FunciDados), //Converte os dados Observable em JSON
                 contentType: "application/json",
                 success: function (data) {
                     alert("Registro incluído com sucesso!");
                     self.funcionarioid(data.funcionarioid);
                     alert("O novo ID do Funcionário :" + self.funcionarioid());
                     GetFuncionarios();
                 },
                 error: function () {
                     alert("Operação Falhou!");
                 }
             });
             //fim
         };

         self.update = function () {
             var url = "/api/Funcionario/" + self.funcionarioid();
             alert(url);
             $.ajax({
                 type: "PUT",
                 url: url,
                 data: ko.toJSON(FunciDados),
                 contentType: "application/json",
                 success: function (data) {
                     alert("Registro atualizado com sucesso.");
                     GetFuncionarios();
                 },
                 error: function (error) {
                     alert(error.status + "<!----!>" + error.statusText);
                 }
             });
         };

         //Função para realizar a operação de DELETE
         self.delete = function (_funcionario) {
             $.ajax({
                 type: "DELETE",
                 url: "/api/Funcionario/" + _funcionario.funcionarioid,
                 success: function (data) {
                     alert("Registro deletado com sucesso");
                     GetFuncionarios();//Refresh the Table
                 },
                 error: function (error) {
                     alert(error.status + "<--e--> " + error.statusText);
                 }
             });
             alert("Selecionado :" + _funcionario.funcionarioid)
         };

         //Função para ler todos os  Funcionarios
         function GetFuncionarios() {
             // chamara Ajax para pegar todos os funcionarios
             $.ajax({
                 type: "GET",
                 url: "/api/Funcionario",
                 contentType: "application/json; charset=utf-8",
                 dataType: "json",
                 success: function (data) {
                     self.Funcionarios(data); //Poe a resposta no ObservableArray
                 },
                 error: function (error) {
                     alert(error.status + "<--e--> " + error.statusText);
                 }
             });
             //fim
         }

         //Função para exibir o registro atualizado
         self.getfuncionarioselecionado = function (_funcionario) {
             self.funcionarioid(_funcionario.funcionarioid),
             self.nome(_funcionario.nome),
             self.titulo(_funcionario.titulo),
             self.nascimento(_funcionario.nascimento),
             self.estadocivil(_funcionario.estadocivil),
             self.sexo(_funcionario.sexo),
             self.admissao(_funcionario.admissao)
         };
     };
     Ko.applyBindings(new FunciViewModel());
    </script>
</body>
</html>

Esta é a versão final do arquivo create.cshtml e esta pronto para ser usado.

Usando MVC, Web API, jQuery e Knockout.js, é realmente fácil desenvolver aplicações Web com dados vinculados com interface ricas do lado do cliente.

O padrão Observable implementado pelo KO nos ajuda a reduzir um monte de código que seria necessário para construir a mesma funcionalidade.

Dessa forma usando knockout.js e a biblioteca jQuery podemos construir aplicações comerciais usando um navegador compatível de forma bem simples.

João 6:48 Eu sou o pão da vida.

João 6:49 Vossos pais comeram o maná no deserto e morreram.

João 6:50 Este é o pão que desce do céu, para que o que dele comer não morra.

Referências:


José Carlos Macoratti