20140520 microsoft webcamp - databinding with knockoutjs

Post on 27-Nov-2014

309 Views

Category:

Software

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Level 250-300 session on KnockoutJS, with 10 examples. Full code at my blog: http://blogit.create.pt/blogs/joaopedromartins Note: in portuguese.

TRANSCRIPT

Data Binding com

Microsoft WebCamp 201420 de Maio de 2014

2 /43

Sobre mim

João Pedro “jota” MartinsCTO

jota@create.pt

@lokijota

http://blogit.create.pt/blogs/joaomartins

http://www.linkedin.com/in/joaopedromartins

3 /43

Agenda

O que é KnockoutJS? Observables Computed Members Observable Arrays Bindings nativos Templates e controlo de fluxo Extensão de Binding Handlers Temas relâmpago: Mapping Plugin, Extenders, KoUtils, Debug/troubleshooting

4 /43

O que é KnockoutJS?

Biblioteca Javascript que ajuda na criação de interfaces dinâmicos sobre um modelo de dados limpo, usando MVVM.

Por outras palavras: é uma framework Javascript de data binding para aplicações Web.

ELEVATOR PITCH

5 /43

Apresentação rápida

Grátis e open source, criado em 2010 por Steve Sanderson Javascript puro – funciona com outras frameworks , server ou client-side Compacto - 47kb ‘minificado’ (~13kb usando gzip) Sem dependências (jQuery opcional, p.ex.) Suporta [praticamente] todos os browsers IE 6+ (!!), Firefox 2+, Chrome, Opera, Safari (desktop/mobile)

Completamente documentado e com comunidade activa Documentação da API, exemplos funcionais, tutoriais interactivos, blogs, Google Group

Versão actual: 3.1.0 e grande foco em retro-compatibilidade

O QUE É KNOCKOUTJS?

6+ 2+

6 /43

Funcionalidades

Bindings declarativos Associação de elementos do DOM a um modelo em Javascript com uma

sintaxe concise e legível Actualização automática do Interface Utilizador e Modelo Sempre que o modelo muda, o IU é actualizado (e vice-versa)

Gestão de dependências Identificação implícita de dependências entre campos do modelo

Templating Geração de interfaces com base nos dados do modelo

O QUE É KNOCKOUTJS?

/437MVVMO QUE É KNOCKOUTJS?

MODEL

Server/DB Javascript+Observables HTML + Bindings

VIEWVIEW MODEL AUTO

User Interface em HTML

Backend de lógica e dados, pode ser qualquer tecnologia

Modelo OO do User Interface, com dados e lógica da UI

Dados e acções

/438Javascript Brothers in Arms

jQuerySubstituto cross-browser para uma API inconsistente do DOM

Mecanismo baixo nível de manipular elementos e event handlers em páginas Web

AngularJSFramework completa alto-nível para desenvolvimento de Single Page Applications (SPA)

Comparável a Durandal

KnockoutJSFramework alto-nível para mapeamento entre modelos de dados e interfaces Web, usando padrão MVVM

KOJS usa jQuery se estiver disponível

O QUE NÃO É KNOCKOUTJS?

9 /43

KnockoutJS em 3 passos

<input data-bind="value: firstName" />

O QUE É KNOCKOUTJS?

Binding declarativ

o

var myViewModel = {firstName: ko.observable(“jota")

};

ko.applyBindings(myViewModel);

Criar observabl

e

Ligar (bind) do ViewModel à View

KOJS 101DEMO 01

11 /43

Sagan

Carl SaganCarl Sagan

Sagan

Target Element Binding Source Object Property

Observables

Encapsular propriedades com a função “observable” ko.observable() ou ko.observable(valor_inicial);

Binding bi-direccional Tanto UI como modelo são actualizados

CONCEITOS BASE

12 /43

Binding bi-direccionalCONCEITOS BASE

<span>Laptop model:</span><input data-bind="value: product.model"/><span>Sales price:</span><span data-bind="text: product.salePrice"></span>

Binding declarativ

o

product: { id: 1001, model: ko.observable(“Surface 2 Pro"), salePrice: ko.observable(1199.95) } ko.applyBindings(product);

Objecto de dados

Ligar UI a dados e vice-versa (wireup)

ObservablesDEMO 02

14 /43

Membros calculados - Computed

Definir uma função que define um valor, e usar isso no binding Ex: Nome completo, Photo Url, Montantes totais

Quando os observables são alterados, os campos computed também são notificados – detecção implícita de dependências

Gestão de “this”… Pode ser necessário passar informação sobre o “this” para o computed

CONCEITOS BASE

15 /43

Definir uma propriedade Computed

vm = {id: ko.observable(1),unitPrice: ko.observable(4199),qty: ko.observable(2)

};

vm.extendedPrice = ko.computed(function () { return this.product() ?

this. unitPrice() * parseInt("0" + this.qty(), 10) : 0; }, vm);

CONCEITOS BASE

observables

Owner (=this)

Computed ObservablesDEMO 03

17 /43

Observable Array

Permite ‘seguir’ os itens de um array, não o seu estado interno Notificações geradas quando itens são Adicionados ou Removidos do

Array Suporta API normais sobre arrays (push, pop, length, …) Não são geradas notificações quando as propriedades de itens do

array são alterados Necessário usar ko.observable() nessas propriedades também

CONCEITOS BASE

18 /43

Exemplo de Observable ArrayCONCEITOS BASE

var myViewModel = {salesPerson: ko.observable(“Luis Calado"),empNum: ko.observable(666),products: ko.observableArray([ { model: “Surface Pro", price: 1749,

id=123 },{ model: “Windows Azure", price: 189,

id=456 }])

};

<span data-bind="text: products().length"></span>

Pré-popular com dados

Agir sobre o observable

array

Observable ArrayDEMO 04

20 /43

Bindings

<input type="text" data-bind="enable: allowEditing, value: salePrice" />

<select data-bind="options: colors, value: selectedColor, optionsText: 'name', optionsValue: 'key'" ></select>

CONCEITOS BASE

Nativos de Knockout

Binding a atributos de elementos

Vários bindings num elemento

21 /43

Bindings nativos (2)CONCEITOS BASE

attr checked click css disable

enable event hasfocus html options

optionsText optionsValue selectedOptions style submit

text uniqueName value visibletext value

click disable

enable

attr

Display and state bindingsText and value bindingsBindings for specific attributes

visible

event

Event bindings

Bindings nativosDEMO 05

/4323Templates: control de fluxoCONCEITOS BÁSICOS

• Se condição “truthy”if• Se condição “falsy”ifnot

• Executar para cada item numa listaforeach• Especificar sub-scope do viewModelwith

24 /43

Templates – inline templates

<tbody data-bind="foreach: lines"><tr>

<td style="width: 100px;"><input data-bind="value: quantity" />

</td> ...</tr>

</tbody>

CONCEITOS BÁSICOS

25 /43

Templates – named templates

<tbody data-bind="template: {name: 'productsTmpl', foreach: lines}"></tbody>

<script type="text/html" id="productsTmpl"> <tr> <td style="width: 100px;">

<input data-bind="value: quantity" /> </td> ...</tr>

</script>

CONCEITOS BÁSICOS

Passar o contexto para a template com o “foreach”

26 /43

Condições

<p data-bind="if: lines().length > 0"><span>Total value:</span><span data-bind="text: grandTotal()"></span>

</p>

CONCEITOS BÁSICOS

Qualquer expressão “truthy”

Especificar o contexto

<div data-bind="with: model"> <div data-bind="text: brand"></div><div data-bind="text: name"></div>

</div>

<div> <div data-bind="text: model().brand"></div><div data-bind="text: model().name"></div>

</div>

CONCEITOS BÁSICOS

Controlo de fluxo e templates (foreach)DEMO 06

29 /43

Controlo de fluxo sem container HTML

Utilização de comentários HTML Comentário usa elementos de control de fluxo if ifnot foreach with Template

<!-- ko foreach: myItems --> …<!-- /ko -->

CONCEITOS BÁSICOS

Parte do motor de templating nativo

do KnockoutJS

Controlo de fluxo sem containerDEMO 07

31 /43

O que são Custom Binding Handlers?

Mecanismo de extensibilidade de bindings

Exemplos Arredondar e apresentar como valor monetário Animar uma transição

fadeVisible Integrar com jQueryUI

jqButton Ratings com estrelas

starRating Fazer logging

CONCEITOS BASE

32 /43

Como criar um Binding Handler

ko.bindingHandlers.fadeVisible = { init: function(element, valueAccessor) { // ...

},

update: function(element, valueAccessor) { // ...

} }

CONCEITOS BASE

Executado na primeira avaliação do binding

Executado depois do init, cada vez que um dos

observables mude

Binding Handler - parâmetros

ko.bindingHandlers.fadeVisible = { init: function(element, valueAccessor, allBindingsAccessor, viewModel) { var shouldDisplay = valueAccessor(); $(element).toggle(shouldDisplay); }, update: function(element, valueAccessor, allBindingsAccessor, viewModel) { var shouldDisplay = valueAccessor(); shouldDisplay ? $(element).fadeIn() : $(element).fadeOut(); } }

Elemento do DOM

Parâmetro binding

Outros bindings do elemento

viewmodel

Custom Binding HandlersDEMO 08

35 /43

Mapping

Mapping Plugin Extensão ao Knockout (download oficial separado) Converte um objecto JS para um objecto observável, recursivamente Possibilidade de parametrizar operação ko.mapping.fromJS(jsdata) e ko.mapping.toJS(viewModel);

Pode ter problemas de desempenho. Alternativa: Knockout Wrap

OUTROS TEMAS

36 /43

Extenders

Permitem adicionar funcionalidade extra aos nossos observables que filtram a forma como notificações são geradas

Ex. de nativos: myViewModel.personName.extend({ rateLimit: 50 }); // limita taxa de eventos myViewModel.personName.extend({ notify: 'always' }); // força sync

Ex. de desenvolvidos à medida: this.firstName = ko.observable(“jota").extend({logChange: "first name"});

OUTROS TEMAS

37 /43

KO Utils

Despistar dados usados para fazer bind com um elemento: ko.dataFor(element) – dados com que o element foi ‘binded’ ko.contextFor(element) – todo o ‘binding context’ disponível para o element DOM

ko.toJS – cria cópia de um viewModel removendo toda a estrutura do KO ko.toJSON – chama toJS e depois converte o resultado para JSON

JSON.stringify(viewModel) ignora funções, e observables são funções… ko.utils.parseJSON(str) – semelhante a JSON.parse. A seguir implica usar mapping plugin ko.utils.arrayMap(str, delegate) – itera num array e aplica um delegate(semelhante a lambda), devolvendo

colecçãovar mappedData = ko.utils.arrayMap(jsonData, function(item) { return new Item(item.name, item.category, item.price);});

ko.utils.arrayForEach(val, delegate) – itera num array e aplica um delegate ko.utils.arrayFilter(val, boolDelegate) – filtra array

OUTROS TEMAS

38 /43

Debug e Troubleshooting

<pre data-bind=“text: ko.toJSON($data, 0, 2)”></pre>

<input data-bind=“uniqueIName: console.log($data), value: description />

Knockout Context Debugger (chrome extension) e dev-console do browser

Performance – quantas vezes dispara um binding? Apenas deve ser observable o que dever ter fluxo bi-direccional

OUTROS TEMAS

Just one more demoDEMO 09

40 /43

Resumindo – KnockoutJS é uma biblioteca…

Específica e pequenaCompatível com vários browsers e outras frameworks

Permite sincronização automática da alterações e suporta melhor estruturação de código Javascript

41 /43

Horas de diversão

Documentação e Download Homepage e documentação: http://knockoutjs.com Blog Steve Sanderson: http://blog.stevensanderson.com Blog Ryan Niemeyer: http://knockmeout.net Código: https://github.com/knockout/knockout/releases

Extras e extensões Knockout Validation: https://github.com/Knockout-Contrib/Knockout-Validation Knockout Wrap: https://github.com/arj03/knockout.wrap Knockout-es5: https://github.com/SteveSanderson/knockout-es5 Knockout Delegated Events: https://github.com/rniemeyer/knockout-delegatedEvents Google Chrome Extension: Knockoutjs context debugger

Comunidade https://groups.google.com/forum/#!forum/knockoutjs http://stackoverflow.com “knockoutjs”

Obrigado!

jota@create.pt

@lokijota

http://blogit.create.pt/blogs/joaomartins

http://www.linkedin.com/in/joaopedromartins

top related