KnockoutJS com ASP.NET MVC3: Utilização na vida real

35
KnockoutJS com ASP.NET MVC 3: Utilização na vida real Marco André Silva http://netpont o.org 28ª Reunião Lisboa - 21/04/2012

description

Apresentação do Marco Silva sobre a utilização de KnockoutJS com ASP .NET MVC 3 na 28a Reunião Presencial da Comunidade NetPonto em Lisboa (http://netponto.org).

Transcript of KnockoutJS com ASP.NET MVC3: Utilização na vida real

Page 1: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KnockoutJS com ASP.NET MVC 3: Utilização na vida real

Marco André Silva

http://netponto.org28ª Reunião Lisboa - 21/04/2012

Page 2: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Patrocinadores desta reunião

Page 3: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Marco André Silva• Consultor Sénior na |create|it|, uma empresa

especializada na área de soluções colaborativas e integração de sistemas.

• Actualmente é responsável pela área de soluções da|create|it|, desenvolvendo também aplicações baseadas em SharePoint, ASP.NET, WCF e outras tecnologias Microsoft.

• Os seus principais interesses são o desenvolvimento de arquitecturas de serviços e interfaces ricas

Page 4: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Agenda

• ASP.NET MVC 3• Knockout JS• Demo – Knockout O Essencial• Integração Knockout JS com ASP.NET MVC 3• Demo – Knockout JS com ASP.NET MVC 3• Experiência de utilização• O futuro• Conclusões

Page 5: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Contexto• Projecto com 6 pessoas

• + 1 ano

• Aplicação Web

• Volume elevado de informação a apresentar

• Experiência de utilização similar a aplicação nativa

• Desafios de usabilidade e interacção com a aplicação

• Facilidade de manutenção e evolução da aplicação

Reflecte a nossa experiência e melhores práticas e não uma verdade universal

Page 6: KnockoutJS com ASP.NET MVC3: Utilização na vida real

ASP.NET MVC 3 - Introdução• Browser faz pedido (GET) a URL

• Rota é determinada

• Controlador é instanciado

• Acção de controlador é invocada

• Controlador processa pedido e retorna modelo para a vista

• Vista (HTML) é elaborada com base no modelo

Model

View Controller

Page 7: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS (KO JS) - Introdução• Biblioteca JavaScript Open source

• Funciona do lado do cliente (browser), e promover interactividade

• Padrão MVVM – Separar lógica de negócio de interface

• Suporte para vários browsers

• Não existem event handlers de JavaScript/Jquery. Existe sim, JavaScript object-oriented e bindings declarativos

• Binding automático em dois sentidos:– Da interface para o modelo– Do modelo para a interface

• Calculo automático de dependências

• Suporte para templating

• Diversos tipos de bindings out-of-box com possibilidade de implementar custom bindings

• Desenvolvido e mantido por Steve Sanderson, colaborador da Microsoft, mas o KO é um projecto pessoal e open-source

• Versão actual 2.0. Versão 2.1 a caminho.

Page 8: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS - MVVM• Informação importada do Modelo para o

ViewModel

• Quando a informação do ViewModel é actualizada é exportada de volta para o Modelo

• Quando a informação do ViewModel é actualizada, a Vista é automaticamente actualizada

• Quando a informação da Vista é alterada, o ViewModel é automaticamente alterado

Model

View ViewModel

Page 9: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Data Binding - ConceitoView Model

Data BindingView Model

Page 10: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Data Binding - Exemplo // ViewModelvar cartLineViewModel = { category: ‘Ships’, product: ‘The Titanic’, quantity: 123};

// View -> Data BindingThe category is <span data-bind=“text: category” />

// Activar KOko.applyBindings(cartLineViewModel);

Page 11: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – ObservablesActualização automática da UI

// ViewModelvar cartLineViewModel = { category: ko.observable(‘Ships’), product: ko.observable(‘The Titanic’), quantity: ko.observable(123)};

// View -> Data BindingThe category is <span data-bind=“text: category” /> The category is <input data-bind=“value: category” />

// Activar KOko.applyBindings(cartLineViewModel);

Page 12: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Computed ObservablesCalculo Automático de Dependências

// ViewModelvar cartLineViewModel = { … subtotal: ko.computed(function() { return this.product().price * this.quantity(); }, this);};

// View -> Data BindingThe sub total is <span data-bind=“text: subtotal” />

// Activar KOko.applyBindings(cartLineViewModel);

Page 13: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Observable Arrays// ViewModelvar cartViewModel = { … lines: ko.observableArray([cartLineViewModel]);};

// View -> Data Binding…<tbody data-bind=“foreach: lines”>…</tbody>

// Activar KOko.applyBindings(cartViewModel);

Page 14: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Form Bindings// ViewModelvar cartViewModel = { … this.lines = ko.observableArray([cartLineViewModel]); this.addLine = function(){this.lines.push(new CartLine())}; this.removeLine = function(line){this.lines.remove(line)};};

// View -> Data Binding…<tbody data-bind=“foreach: lines”>… <td> <a href='#' data-bind=“click: $parent.removeLine”>Remove</a> </td></tbody><button data-bind=“click: addLine”>Add product</button>

// Activar KOko.applyBindings(cartViewModel);

Page 15: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – Ler e Gravar• Formato dados: JSON• $.ajax

• Gravar – Conversão de viewModel para JSON

• ko.toJSON ou• Mapping plugin

– $.ajax(urlGravar, JSON)– ko.toJSON também útil para fazer debug

• Ler– JSON = $.ajax(urlObter)– Criar / Actualizar viewModel

• Manual ou• Mapping Plugin

• Mapping Plugin– Biblioteca separada– Converte “cegamente” propriedades em Observables, e arrays em ObservableArrays– Ler:

• ko.mapping.fromJS / fromJSON

– Gravar:• ko.mapping.toJS / toJSON

Page 16: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS – O essencial

demonstração

Page 17: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Resumo KO JS• MVVM:

– View (HTML) / ViewModel (JavaScript) / Model (JavaScript)

• Conceito observable– Calculo automático de dependências

• Conceito de bindings:– Declarativos– Sincronização modelo UI automático

• Funções JavaScript para responder a bindings:– Validações– Lógica de negócio

• Controlo de Fluxo:– Foreach– if

• Formato JSON para leitura / gravação (interacção com o servidor)

Page 18: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS - Integração com ASP.NET MVC 3

Page 19: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS - Integração com ASP.NET MVC 3

• Paradigma diferente do desenvolvimento MVC normal:– Geração da página no cliente em vez de no servidor

– View Models desenhados de forma diferente a pensar no cliente

– Lógica de negócio no cliente

Page 20: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS - Integração com ASP.NET MVC 3

• Inclusão referência:– <script type='text/javascript' src='knockout.js'></script>

• Estruturação de Views e inclusão de JavaScripts

• Models MVC Models Knockout JS– Geração de modelos JavaScript Leitura– Resultados de acções em formato JSON Leitura

• Models Knockout JS Models MVC– Model Binding MVC 3 a partir de JSON Gravação

• Elaboração de Views– Model Validation & Data Annotations

• Alternativa: Utilização de HTML Helpers

Page 21: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS – MVC 3Estruturação de Views e JavaScriptMVC View// View model (se necessário)@model CartViewModel

// KO JS references<script src="@Url.Content("~/Scripts/Knockoutjs/knockout-latest.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/Knockoutjs/knockout.mapping-latest.js")" type="text/javascript"></script>…// View scripts@section Scripts{ // Passagem de parâmetros para JavaScript <script language="javascript" type="text/javascript"> var settings = { urlSave: '@Url.Action(“Save", “Cart")’, urlGet: '@Url.Action(“Get", “Cart")’, id: @Model.Id // Se existir View Model }; </script>

// KO JS ViewModel <script src="@Url.Content("~/Scripts/App/Cart.js")” type="text/javascript"></script>}

JavaScript // KO JS ViewModel var cartViewModel = { serverModel: {} }

Page 22: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS – MVC 3Models MVC Models KO – Geração inline na vista MVCMVC View// View model (necessário!!!)@model CartViewModel…// View scripts@section Scripts{ // Passagem de parâmetros para JavaScript <script language="javascript" type="text/javascript"> var settings = { … // Geração de modelo JavaScript a partir de classe de modelo MVC clientModel: @(Html.InterpretJson(Model)) }; </script>

// KO JS ViewModel <script src="@Url.Content("~/Scripts/App/Cart.js")” type="text/javascript"> </script>}

JavaScript // Gerar Client Model a partir do model contido na página cartViewModel.serverModel = ko.mapping.fromJSON(serverModel);

Page 23: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS – MVC 3Models MVC Models KO – Resultado de acção em formato JSONMVC View…// View scripts@section Scripts{ // Passagem de parâmetros para JavaScript <script language="javascript" type="text/javascript"> var settings = { … }; </script>

// KO JS ViewModel <script src="@Url.Content("~/Scripts/App/Cart.js")” type="text/javascript"></script>}

JavaScript // Dialogo de aguarde ToggleLoadingDialog();

// Obter model do servidor Acção Get do controlador var serverModel = GetServerModel();

// Gerar Client Model a partir de model do servidor cartViewModel.serverModel = ko.mapping.fromJSON( serverModel);

MVC Controllerpublic ActionResult Edit(int id){ // Retornar vista Pode ter modelo (tipicamente simples), ou ser apenas HTML markup return View(); }

public ActionResult Get(int id){ // Criar modelo CartViewModel viewModel = BuildViewModel( id);

// Retornar modelo em JSON return Json(viewModel); }

Page 24: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS – MVC 3Models KO Models MVC – Model Binding MVC 3 a partir de JSONJavaScript var cartViewModel = { save: function() { // Validar página / modelo … // Dialogo de aguarde ToggleLoadingDialog();

// Submeter pedido de gravação ao servidor $.ajax(ko.mapping.toJSON( cartViewModel.serverModel);

MVC Controller[HttpPost]public ActionResult Save(Cart cart){ // Gravar Repository.Save(cart);

// Retornar resultado relevante da acção return Json(result);}

Model Classpublic class Cart{ // Cart lines public List<CartLine> Lines { get; set; } }

public class CartLine{ public string Category { get; set; } public string Product { get; set; } public int Quantity { get; set; } public int SubTotal { get; set; }}

Page 25: KnockoutJS com ASP.NET MVC3: Utilização na vida real

KO JS – MVC 3Elaboração de ViewsMVC View@model CartViewModel…// Percorrer cada linha <tbody data-bind='foreach: cartViewModel.serverModel.Lines'> … // Com o produto da linha <td class='price' data-bind='with: Product'> // Produto tem preço <span data-bind='text: formatCurrency(price)'> </span> </td> // Se a linha tiver um produto, mostrar quantidade. Incluir validações <td class='quantity'> <input name="@Html.NameFor(m => m.Product.Quantity)" data-bind='visible: product, value: quantity, valueUpdate: "afterkeydown"' @Html.ValidationAttributesFor(m => m.Product.Quantity) /> @Html.ValidationMessageFor(m => m.Product.Quantity) </td> // Se a linha tiver um produto, mostrar subtotal <td class='price'> <span data-bind='visible: product, text: formatCurrency(subtotal())' > </span> </td> // Link para remover linha de produto. Chama função do view model <td> <a href='#' data-bind='click: $parent.removeLine'>Remove</a> </td> …</tbody>…// Botões de acção. Chamam funções do view Model <button data-bind='click: addLine'>Add product</button><button data-bind='click: save'>Submit order</button>

Page 26: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Knockout JS com ASP.NET MVC 3

demonstração

Page 27: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Experiência de utilizaçãoO menos bom

• Bugs de Model Binding de MVC

• Mapping Plugin de KO e modelos grandes (Script running too long)

• Execução de pedidos AJAX manualmente (GET / POST)

• Performance do serializer JSON usado no MVC

• Articulação com MVC Data Annotation Validations

Page 28: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Experiência de UtilizaçãoO bom

• Model Binding de JSON

• Geração de modelos cliente a partir de modelos servidor

• Mapping Plugin de KO

• Data Binding e Facilidade de criação da UI no cliente

• Trabalhar no cliente com objectos em vez de eventos

• Facilidade de construção da aplicação

• Fluidez da aplicação no cliente

• Essencial para desenvolver Single Page Applications!!!!

Page 29: KnockoutJS com ASP.NET MVC3: Utilização na vida real

O futuro – MVC 4Servidor Cliente

Web UIHTML/CSS/JS

WebAPI

Data ServicesJSON/XML

Visible UIHTML/CSS

Application LayerJavaScript

Data Access LayerJavaScript

Local Storage HTML 5

UpShot.js

Knockout.js

History.js

Navigation APIs

MVC

Page 30: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Conclusões• As duas tecnologias resultam bem em conjunto

• Desenvolvimento mais facilitado

• Aplicações mais fluidas e rápidas

• Grande foco na interacção com o utilizador

• Conceitos aplicam-se também fora de aplicações Web (ex: Apps para Windows 8)

Page 31: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Questões?

Page 32: KnockoutJS com ASP.NET MVC3: Utilização na vida real

ReferênciasASP.NET MVC

– http://www.asp.net/mvc

ASP.NET MVC 4– http://www.asp.net/mvc/mvc4

Knockout JS– http://www.knockoutjs.com

Knockout JS Tutorials– http://learn.knockoutjs.com/

Page 33: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Patrocinadores desta reunião

Page 34: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Próximas reuniões presenciais

• 21-04-2012 – Abril• 26-05-2012 – Maio• 02-06-2012 – Junho (Coimbra)• 16-06-2012 – Junho• 21-07-2012 – Julho

Reserva estes dias na agenda! :)

Page 35: KnockoutJS com ASP.NET MVC3: Utilização na vida real

Obrigado!

Marco André [email protected]