Knockout - é possível combinar ligações de seleção padrão com uma ligação personalizada?
Isso não funciona (ligação personalizada é chamada, mas dropdown está vazio)
<select id="parentArea" class="chosen-select" data-bind="
chosen:{},
options: parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: selectedParentArea">
</select>
Mas isso funciona (dropdown é preenchido)
<select id="parentArea" class="chosen-select" data-bind="
options: parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: selectedParentArea">
</select>
Gostaria de adicionar uma ligação personalizada ao menu suspenso, mas não sei como fazer isso.
Ligação personalizada é simples
ko.bindingHandlers.chosen = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
console.log('chosen', element);
$(element).chosen({});
}
};
ATUALIZAR
.escolhido({});
é um método de outra parte do Javascript (harvesthq.github.io/chosen).
Eu percebi que quando é comentado, o trabalho de ligação restante. O que eu realmente preciso é rodar "$ (element) .chosen ({});" Depois de todos os outros acabamentos de ligação.
ATUALIZAÇÃO 2
Quando eu aplico 'escolhido' manualmente depois que todas as ligações são aplicadas, ele funciona bem. Por exemplo, eu posso usar um botão que executa este JS
function run() {
$('.chosen-select').chosen({});
};
Eu só preciso fazer isso automaticamente (uma função de retorno de chamada?) Quando todas as ligações estão completas. Eu não sei como fazer isto.
ATUALIZAÇÃO 3
"parentAreas" não é um array estático. É carregado de um serviço da web:
function ViewModel() {
var self = this;
self.init = function () {
//load parent areas from web service
};
self.init(); //Running the init code
}
ko.applyBindings( new ViewModel());
Desejo inicializar a ligação personalizada da caixa "escolhida" quando as áreas pai estiverem prontas.
ATUALIZAÇÃO 4
Nova versão (funciona, mas não é reutilizável, pois possui ligações codificadas)
ko.bindingHandlers.chosen = {init: function (elemento, valueAccessor, allBindingsAccessor, viewModel, contexto) {
viewModel.parentAreas.subscribe(function(newParentAreas) {
if (newParentAreas && newParentAreas.length > 0) {
ko.applyBindingsToNode(element, {
options: viewModel.parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: viewModel.selectedParentArea
});
$(element).chosen({});
}
});
}
};
// e binding é apenas data-bind = "chosen: {}
ATUALIZAÇÃO 5 Evitar a inicialização múltipla (caminho hacky)
ko.bindingHandlers.parentAreaComboBox = {
initialised: false,
init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
viewModel.parentAreas.subscribe(function (newParentAreas) {
if (newParentAreas && newParentAreas.length > 0) {
if (ko.bindingHandlers.parentAreaComboBox.initialised) {
return;
}
ko.applyBindingsToNode(element, {
options: viewModel.parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: viewModel.selectedParentArea
});
$(element).chosen({});
ko.bindingHandlers.parentAreaComboBox.initialised = true;
}
});
}
};
ATUALIZAÇÃO 6
Eu escrevi solução genérica (veja minha resposta abaixo)