Uma propriedade observavel do knockoutjs permite notificar alguns “assinantes” quando ocorre uma mudação de estado. Isso é útil quando desejamos adicionar alguma funcionalidade para propriedade observable. Isso é possível no knockoutjs com “extenders”. Podemos criar um “extender” dessa forma:
ko.extenders.concat = function (obs, add) { var valorObs = obs(); obs(valorObs + add); return obs; };
Nesse extender simples, estamos definindo a “assinatura” dele com seu nome: “concat” e com dois parâmetros
* obj: Receberá a propriedade observable
* add: Parâmetro adicional que pode ser utilizado para passar qualquer parâmetro a ser utilizado no extender
A implementação é bem simples, primeiro armazenamos o valor do observable na variável “valorObs”, como se trata de um observable devemos chamar ele com “()”, em seguida definimos um novo valor para o observable, com o valor atual mais algum sufixo, e por último retornamos o observable modificado. Para utilizar esse extender devemos usar ele dessa forma:
function ViewModel(){ this.Nome = ko.observable("Maria").extend({ concat: '!' }); } $(function(){ window.viewModel = new ViewModel(); ko.applyBindings(window.viewModel); });
Acima temos uma propriedade observable chamada “Nome”, que tem o valor inicial igual há “Maria”, e que faz uso do extender “concat”, passando como parametro o valor “!”. Se visualizarmos no console do navegador, informando window.viewModel.Nome(), teremos o valor: “Maria!”, porem se atualizarmos o valor (informe no console do navegador window.viewModel.Nome(“Novo valor”)), o valor não atualizará corretamente, isso corre por que o extender apenas configura um evento, você deve implementar uma previsão de mudança de estado. Vamos para um exemplo.
ko.extenders.concat = function (obs, add) { var resultado = ko.computed({ read: obs, write: function(valor) { obs(valor + add); } }).extend({ notify: 'always' }); return resultado; };
Acima mudamos um pouco a implementação do extender; Primeiro definimos uma variável que fica responsável por armazenar o observable computado.
O método “read” retorna o valor de obs apenas;
O método write ao receber uma notificação de mudança é acionado, e nós determinamos que o valor retornado deve ser o valor passado por parâmetro “valor” concatenado com o sufixo.
E por último determinamos que o “computed” deve utilizar o “extender” “notify” com parâmetro “always”, isso significa que o valor deve sempre estar atualizado, esse é um “extender” implementado pelo KO; Assim temos:
ko.extenders.concat = function (obs, add) { var resultado = ko.computed({ read: obs, write: function(valor) { obs(valor + add); } }).extend({ notify: 'always' }); return resultado; }; function ViewModel(){ this.Nome = ko.observable().extend({ concat: '!' }); } $(function(){ window.viewModel = new ViewModel(); window.viewModel.Nome("Maria"); ko.applyBindings(window.viewModel); });
No próximo post vou mostrar como utilizar validação no KO (utilizando extenders!), acredito que ficará mais claro, como utilizar os extenders
Até a próxima pessoal!