我正在尝试创建一种自定义下拉列表,它将具有一个方法名称,从中获取其所有元素,在敲除模型绑定之前,它应该等待从给定的方法填充列表然后开始默认行为。
到目前为止,我成功地从给定方法填充数据。但问题是如何告诉knockout绑定等到我的init方法完成其异步工作。
ko.bindingHandlers.serviceMethod = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var serviceName, optionsValue, optionsText, value, optionsCaption, isCompleted;
if (element.nodeName == 'SELECT') {
optionsValue = allBindings().optionsValue || 'value';
optionsText = allBindings().optionsText || 'text';
serviceName = valueAccessor();
var l = $(element);
serviceName.apply().done(function (results) {
l.empty();
$.each(results.List, function (j, result) {
l.append($("<option />").val(result[optionsValue] || '').text(result[optionsText] || ''));
})
});
}
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
//what to do now in order to let knockout wait for list to be populated
}
}
我的绑定是
<select name="state" data-bind="serviceMethod:registrationService.getAllStates,value: model.state" id="ddlState"></select>
答案 0 :(得分:1)
您可以在数据可用之前禁用输入元素,Extender可以执行此操作。
标记:
<select data-bind="serviceMethod:getOptions, options: options, enable:options.enable></select>
viewmodel:
function viewModel(){
this.options=ko.observableArray().extend( { enabled:false});
}
绑定处理程序:
ko.bindingHandlers.serviceMethod = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var getOptionsFunction=valueAccessor();
// deferred implemented as a callback
getOptionsFunction(function(r){
allBindings().options(r);
// call extender observable to enable the input
allBindings().options.enabled(true);
} );
},
update:function (element, valueAccessor, allBindings, viewModel, bindingContext) {
}
扩展器:
ko.extenders.enabled = function(target, option) {
target.enabled=ko.observable(option);
return target;
};
注意:我会将逻辑移到视图模型中,在我们的项目中,我们犯了错误,在应该转到viewModels的绑定处理程序中添加了太多编码。
答案 1 :(得分:1)
这就是我实现它的方式,首先我将淘汰赛扩展为
ko.extenders.asyncList = function (target, option) {
var _callbackF = [];
var result = ko.computed({
read: function () {
if (!target.populated()) {
option.apply().done(_addintoList);
}
return target;
},
deferEvaluation: true
});
target.populated = ko.observable(false);
target.refresh = function () {
target.populated(false);
}
var _addintoList = function (aData) {
ko.utils.arrayForEach(aData.List, function (item) {
target.push(item);
});
if (_callbackF != undefined) {
$.each(_callbackF, function (_f) {
_f.apply();
});
_callback = undefined;
}
target.populated(true);
}
return result();
}
然后使用此扩展程序查看模型,如
staticData: function () {
var self = this;
var def = $.Deferred();
self.allStates = ko.observableArray().extend({ asyncList: registrationService.getAllStates });
self.hearUsAll = ko.observableArray().extend({ asyncList: registrationService.getAllSources });;
self.populated = ko.computed({
read: function () {
if (this.allStates.populated() && this.hearUsAll.populated()) {
return def.resolve(true);
}
return def;
},
deferEvaluation: true
}, this);
然后我的主要功能就像
一样使用它this.staticData.populated().done(
function (d) {
ko.applyBindings({ model: self.dataModel, staticData: self.staticData, view: self.viewModel })
});