icon[1]

KnockoutJS – Mantendo propriedades tipadas com extenders 2


Fala galera, beleza?!

Hoje começo uma serie de posts falando sobre knockoutjs para quem ainda não conhece esse framework javascript, considero a leitura do blog do meu amigo @elemarjr aqui.

Problematica

Quando trabalhamos com inputs todos os dados lá são strings, e é evidente que isso não é diferente usando o knockoutjs. Todas minhas propriedades observables vão ser do tipo string quando forem setadas a partir do change do input, e isso pode causar problemas com processos que fazemos no nosso objeto.

Por exempo, tenho uma entidade pessoa que contem tres propriedades, são elas:

  • Nome
  • Nascimento
  • Idade(essa somente leitura)
Considere o seguinte código:
[javascript]function viewModel(){
this.Nome = ko.observable("Alberto");
this.Nascimento = ko.observable($.datepicker.parseDate("dd/mm/yy", "16/03/1990")).extend({date:{}});
this.Idade = ko.computed(function(){
var today = new Date();
today.clearTime();
var birthday = new Date(this.Nascimento());

var currentYear = today.getFullYear();

var birthdayYear = this.Nascimento().getFullYear();
birthday.setFullYear(currentYear);
return currentYear – birthdayYear + (today >= birthday ? 0 : -1);
}, this);
}[/javascript]

Como podem ver o viewModel é composto de 2 observables e um computed.Na propriedade computada(caculada) Idade, nós não temos a preocupação de ficar convertendo valores, parseDate, Int, Float ou qualquer que seja o tipo em questão, simplesmente zeramos o horário da data atual pois a data que veio da View é sem horário, e ai é só usar os métodos de data para fazermos os cálculos e descobrir a data do individuo.

Mas a diferença aqui está na propriedade nascimento que contem o a chamada a função extend do observable. A função do extend é simplesmente estender os observables, e para isso é so adicionarmos nosso extensor dessa maneira:

[javascript]ko.extenders.date = function(target, option) {
target.subscribe(function(newValue) {
if( typeof newValue == "string") {
var typedValue = $.datepicker.parseDate("dd/mm/yy", newValue);
target(typedValue);
}
return true;
});
return target;
};[/javascript]

O Knockout oferece um objeto para adicionar as extensões, no código acima podemos ver que adicionamos uma função date no objeto ko.extenders, ele é o container de extensões. A função que o extender recebe tem 2 parâmetros, a propriedade em questão(observable) e as opções que você passou, no meu caso passei um objeto vazio, na terceira linha do primeiro código. Você também pode inserir varias extensões em um unico observable, é so passar os outros extensores no objeto, como por exemplo:

this.Nome = ko.observable("Alberto").extend({ ext1: {}, ext2: {}, etc: {}});

Em execução

[jsfiddle url=”http://jsfiddle.net/AlbertoMonteiro/sjmsv/11″ height=”350px” include=”result,html,js”]

O link do fiddle é esse http://jsfiddle.net/AlbertoMonteiro/sjmsv/11.

Era isso!


sobre Alberto Monteiro

Desenvolvedor no Grupo Fortes, cuja principal área de conhecimento são em tecnologias Microsoft, como Windows Forms / Services, WPF, ASP.NET(MVC/WEB API), Windows Phone, EF. Gosta de sopa de letrinhas(SOLID, DDD, TDD, BDD, IoC, SoC, UoW), possui aplicações de Windows Phone publicadas no marketplace, já contribuiu no jQuery UI. Atualmente trabalha com ASP.NET MVC / Web API, Windows Azure, Amazon AWS, jQuery/UI, Knockout, EF, Ninject, AutoMapper, Restfulie, SignalR, KendoUI.

  • Pedro

    Não está funcionando.

  • Valeu Pedro, agora está funcionando!