[英]custom drop down list in knockout
我正在嘗試創建一種自定義下拉列表,它將具有一個方法名稱,從中獲取其所有元素,並且在敲除模型綁定之前,它應該等待列表從給定的方法填充,然后啟動它的默認值行為。
到目前為止,我成功地從給定方法填充數據。 但問題是如何告訴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>
您可以禁用輸入元素,直到數據可用, Extender可以執行此操作。
標記:
<select data-bind="serviceMethod:getOptions, options: options, enable:options.enable></select>
視圖模型:
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的綁定處理程序中放入太多編碼。
這就是我實現它的方式,首先我擴展淘汰賽
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 })
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.