淘汰赛 - 是否可以将标准选择绑定与自定义绑定相结合? [英] Knockout - is it possible to combine standard select bindings with a custom binding?
问题描述
这不起作用(调用自定义绑定但下拉列表为空)
This does NOT work (custom binding is called but dropdown is empty)
<select id="parentArea" class="chosen-select" data-bind="
chosen:{},
options: parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: selectedParentArea">
</select>
但这有效(下拉列表已填充)
But this works (dropdown is filled)
<select id="parentArea" class="chosen-select" data-bind="
options: parentAreas,
optionsCaption: 'Choose...',
optionsText: 'Label',
value: selectedParentArea">
</select>
我想在下拉菜单中添加自定义绑定,但不知道该怎么做.
I would like to add a custom binding to the dropdown but not sure how to do it.
自定义绑定很简单
ko.bindingHandlers.chosen = {
init: function(element, valueAccessor, allBindingsAccessor, viewModel) {
console.log('chosen', element);
$(element).chosen({});
}
};
更新
.chosen({});
.chosen({});
是来自另一段 Javascript (harvesthq.github.io/chosen) 的方法.
is a method from another piece of Javascript (harvesthq.github.io/chosen).
我意识到当它被注释掉时,剩下的绑定工作.我真正需要的是运行$(element).chosen ({});"在所有其他绑定完成后.
I realised that when it is commented out, the remaining binding work. What I really need is to run "$(element).chosen ({});" AFTER all other binding finish.
更新 2
当我在应用所有绑定后手动应用选择"时,效果很好.例如,我可以使用运行此 JS 的按钮
When I apply 'chosen' manually after all the bindings are applied, it works well. Eg I can use a button which runs this JS
function run() {
$('.chosen-select').chosen({});
};
我只需要在所有绑定完成后自动执行(回调函数?).我不知道该怎么做.
I just need to do it automatically (a callback function?) when all bindings are complete. I do not know how to do it.
更新 3
"parentAreas" 不是静态数组.它是从网络服务加载的:
"parentAreas" is not a static array. It is loaded from a web service:
function ViewModel() {
var self = this;
self.init = function () {
//load parent areas from web service
};
self.init(); //Running the init code
}
ko.applyBindings( new ViewModel());
我想在父区域准备好时初始化选择的"框自定义绑定.
I want to initialise "chosen" box custom binding when parent areas are ready.
更新 4
新版本(有效但不可重用,因为它具有硬编码绑定)
New version (works but is non-reusable since it has hardcoded bindings)
ko.bindingHandlers.chosen = {init: 函数(元素、valueAccessor、allBindingsAccessor、viewModel、context){
ko.bindingHandlers.chosen = { init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
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({});
}
});
}
};
//而绑定只是 data-bind="chosen:{}
// and binding is just data-bind="chosen:{}
更新 5避免多次初始化(hacky 方式)
UPDATE 5 Avoiding multiple initialisation (hacky way)
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;
}
});
}
};
更新 6
我已经编写了通用解决方案(请参阅下面的答案)
I've written generic solution (see my answer below)
推荐答案
这是一种依赖于绑定顺序的反模式.
Its a antipattern that you depend on the order of bindings.
如果您有一个自定义绑定需要其他绑定在其自身之前运行,您应该从自定义绑定中调用这些绑定,如
If you have a custom binding that needs other bindings to run before itself you should call those bindings from the custom binding like
ko.applyBindingsToNode(element, { options: arr, value: val });
然后做 $(element).chosen
这篇关于淘汰赛 - 是否可以将标准选择绑定与自定义绑定相结合?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!