Date post: | 27-Nov-2014 |
Category: |
Software |
Upload: | joao-martins |
View: | 301 times |
Download: | 0 times |
Data Binding com
Microsoft WebCamp 201420 de Maio de 2014
2 /43
Sobre mim
João Pedro “jota” MartinsCTO
@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!
@lokijota
http://blogit.create.pt/blogs/joaomartins
http://www.linkedin.com/in/joaopedromartins