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!