Utilizando knockout.js como atualizar a lista de um select à partir da escolha em outro select? Pra muitos pode ser simples de cara, mas vou adimitir: para mim não foi, fui complicando às coisas ao invés de simplificar, quebrei um pouco a cabeça com isso e não tive bons resultados. Até que, lendo um post de um blog que falava sobre observables computed me veio a iluminação! E resolvi partilhar vai que ajudo alguém.
Suponhamos uma aplicação na qual serão escolhidos items, estes itens estão organizados em categorias. Em uma lista seleciono a categoria, e à partir da minha seleção uma segunda lista é abastecida com as opções daquela categoria. Vou ser sincero, Pra começar vejamos uns dados de exemplo:
var produtos = [
{
grupo:"higiene pessoal",
itens:[{'nome':'creme dental','valor':6.95},
{'nome':'shampoo','valor':12.49}]
},
{
grupo:"material de limpeza",
itens:[{'nome':'sabão em pó 2kg','valor':13.80},
{'nome':'detergente 500ml','valor':2.80}]
},
{
grupo:"padaria",
itens:[{'nome':'biscoito de polvilho 500g','valor':4.5},
{'nome':'pão de forma integral','valor':8.35}]
}
];
A seguir nosso html:
<label>Categoria:</label><select data-bind="options:produtos,
optionsText:'grupo',
value:categoriaEscolhida,
optionsCaption:'categoria...'"></select>
<label>Produto:</label><select data-bind="options:itens,
optionsText:'nome',
value:itenEscolhido,
optionsCaption:'Escolha o item'"></select>
E por último nosso código javascript:
var MarketModel = function(){
this.produtos = ko.observableArray(produtos);
this.categoriaEscolhida = ko.observable(this.produtos()[0]);
this.itens = ko.computed(function(){
return this.categoriaEscolhida().itens;
},this);
};
A mágica acontece no observable do tipo
computed. Resumidamente, pois a documentação é muito clara, computed é um campo calculado que sempre será atualizado quando as variáveis observáveis das quais ele depende forem atualizadas.Assim, toda vez que categoriaEscolhida for atualizada, itens também será. Simples assim.