我得到了一些KO代码来维护:
<div class="formField" id="formFieldWorkflowStatus">
<div id="comboWorkflowStatus" data-bind="combobox: workflowStatusModel"></div>
</div>
<div class="formField" id="formFieldSalesStatus">
<div id="comboSalesStatus" data-bind="combobox: salesStatusModel"></div>
</div>
它似乎在它后面使用这个映射JS文件:
(function (app, ko) {
app.namespace("mappers");
function test()
{
convertedObject.salesStatuses
}
var
config = {
"consignments": {
create: mapInlineNotes
},
"charities": {
create: mapInlineNotes
},
"gifts": {
create: mapInlineNotes
},
ignore: ["saleStatus", "saleStatuses"]
},
map = function (json) {
var convertedObject = ko.utils.parseJson(json);
var model = ko.mapping.fromJS(convertedObject, config);
model.salesStatusModel = new ListModel({
isRemoteSource: false,
currentValue: convertedObject.selectedSalesStatus,
data: convertedObject.salesStatuses,
onlyPreparedValues: true,
allowNull: false,
readonly: true
});
model.workflowStatusModel = new ListModel({
isRemoteSource: false,
currentValue: convertedObject.selectedWorkflowStatus,
data: convertedObject.workflowStatuses,
onlyPreparedValues: true,
allowNull: false,
readonly: true
});
return model;
},
toJS = function (model) {
return ko.mapping.toJS(model);
},
unmapConsignment = function (consignment) {
return ko.mapping.toJS(consignment);
},
mapConsignment = function (data, consignment) {
if (!consignment) {
return mapInlineNotes({ data: data });
}
return ko.mapping.fromJS(data, consignment);
};
function mapInlineNotes(options) {
return app.mappers.inlineNoteContainer.map(options.data);
}
app.mappers.consignment = {
map: map,
toJS: toJS,
unmapConsignment: unmapConsignment,
mapConsignment: mapConsignment
};
})(app, ko);
我发现的所有例子都不是这样的,并使用如下内容:
<select data-bind="options: workflowStatuses, value: selectedWorkflowStatus, optionsText: 'name', optionsCaption: 'Choose a make'"></select>
但这对我不起作用。顶部的东西是这样的,它们是从DB填充的两个下拉列表,但它们无论如何都没有链接在一起。我需要第二个能够根据第一个选择的内容进行过滤。
我可以捕捉哪些事件来捕捉顶部下拉列表更改?
在正常的MVC中这一切都很容易,但是对于KO我不知道该怎么做而且真的很令人沮丧!
所以在我被迫完全抛弃KO并在普通的MVC中重写它之前,任何帮助都会非常受欢迎。
更新:
我找到了这个文件(knockout.combobox.js):
/// <reference path="jquery-1.7.js" />
/// <reference path="knockout-2.2.1.debug.js" />
/// <reference path="jquery-ui-1.8.16.js" />
// Alex B
(function ($, ko) {
var defaultKeyDownTemplateName = "defaultTemplate";
var defaultChangeComboboxTemplateName = "specialTemplate";
var defaultKeyDownTemplate = "<input type=\"text\" class='ignoreReadonly' data-bind=\"readonly: $data.readonly, enable: $data.editable, autocomplete: $data, value: $data.selected.value, valueUpdate: 'afterkeydown'\"/><button style='opacity: 1' tabindex=\"-1\" title=\"Show All Items\" type=\"button\" data-bind=\"enable: $data.editable, visible: !($data.nobutton), click: $data.showAll, jqueryui: {widget:'button', options:{icons:{primary:'ui-icon-triangle-1-s'}, text: false}}\"> </button>";
var defaultFocusChangeTemplate = "<input type=\"text\" class='ignoreReadonly' data-bind=\"readonly: $data.readonly, enable: $data.editable, autocomplete: $data, value: $data.selected.value\"/><button style='opacity: 1' tabindex=\"-1\" title=\"Show All Items\" type=\"button\" data-bind=\"enable: $data.editable, visible: !($data.nobutton), click: $data.showAll, jqueryui: {widget:'button', options:{icons:{primary:'ui-icon-triangle-1-s'}, text: false}}\"> </button>";
var textareaTemplateName = "textAreaTemplate";
var textareaTemplate = "<textarea class=\"elastic\" type=\"text\" data-bind=\"readonly: $data.readonly, enable: $data.editable, autocomplete: $data, value: $data.selected.value, valueUpdate: 'afterkeydown'\"/>";
var templateEngine = new ko.nativeTemplateEngine();
ko.bindingHandlers.combobox = {
init: function (element, valueAccessor) {
templateEngine.addTemplate(defaultKeyDownTemplateName, defaultKeyDownTemplate, element);
templateEngine.addTemplate(textareaTemplateName, textareaTemplate, element);
templateEngine.addTemplate(defaultChangeComboboxTemplateName, defaultFocusChangeTemplate, element);
$("textarea.elastic").elastic();
return { 'controlsDescendantBindings': true };
},
update: function (element, valueAccessor, allBindingsAccessor) {
var model = ko.utils.unwrapObservable(valueAccessor());
if (allBindingsAccessor().enable) {
var enabled = ko.utils.unwrapObservable(allBindingsAccessor().enable);
model.editable = enabled;
}
if (model.templateName) {
ko.renderTemplate(model.templateName, model, { templateEngine: templateEngine }, element, "replaceNode");
} else {
ko.renderTemplate(defaultKeyDownTemplateName, model, { templateEngine: templateEngine }, element, "replaceNode");
}
}
};
})(jQuery, ko);
And also found:
ko.bindingHandlers.comboboxSelectedValue = {
init: function (element, valueAccessor) {
$(element).bind("change", function () {
var accessor = valueAccessor();
if (ko.isObservable(accessor)) {
accessor(element.selectedIndex != -1 ? $(element).val() : null);
} else {
valueAccessor(element.selectedIndex != -1 ? $(element).val() : null);
}
});
},
update: function (element, valueAccessor) {
if (!$(element).data("combobox")) {
$(element).combobox(); //it is here (not in init method) to provide sorting, because there are no select options rendered by ko by the time init method is called
}
var value = ko.utils.unwrapObservable(valueAccessor());
if (value != null) {
$(element).combobox("setSelectedValue", value);
} else {
$(element).combobox("clearSelected");
}
}
};
in a knockout.extentions.js file.
Hopefully that helps?
Someone on another forum posted this:
//Creates an observable array which changes its contents automatically, based on another value
var filteredWorkflowStatuses=ko.computed(function(){
//Some kind of filtering, e.g
return ko.utils.arrayFilter(convertedObject.workflowStatuses(), function(item){
return convertedObject.selectedSalesStatus() && convertedObject.selectedSalesStatus().someProperty()==item.someProperty();
});
});
这似乎是我需要做的事情但是无法弄清楚我如何根据从WorkFlowStatus下拉列表中选择的值来过滤我的salesstatus下拉列表。目前SalesStstus下拉列表显示所有值,我需要根据WorkFlowStatus下拉列表中选择的内容对其进行过滤。
基本上,当第一个下拉列表(工作流程状态被更改时,我需要第二个下拉列表(销售状态)来过滤其结果。例如,当工作流程状态为保留时,销售状态将显示委托,保留,礼品,慈善机构。状态为On Offer,销售状态将显示On Consignment,On offer和On Loan作为选项。另外还有更多......
希望有道理吗?
非常感谢帮助谢谢! :)
答案 0 :(得分:2)
您不会挂钩事件来观察Knockout中更改的值。窗口小部件绑定到可观察对象,因此值的更改将显示在viewmodel中。您subscribe让那些可观察的人在他们改变时采取行动,或者你写了隐含订阅的computed observables。
如果你是Knockout的新手并且这段代码刚被扔到你的腿上,请花一点时间来完成Knockout tutorial。这会让你更好地感受到Knockout接近事物的方式。你需要很好地理解Knockout,至少在自定义绑定处理程序方面。看起来你得到的东西需要一些重写来获得你想要的功能。
因为它是一个自定义小部件,所以它可能不会触发任何标准事件。我可以给你的最好的建议(没有完成所有的代码,也没有时间来完成所有这些代码)是在workflowStatusModel
的定义之后添加这些代码:
model.workflowStatusModel.subscribe(function (newValue) {
console.debug("Hey, it changed!", newValue);
});
如果您从中获取控制台输出,那么您可以在其中处理对其的更改。否则,查看ListModel
的定义,了解可能存在您正在寻找的值的可观察成员,并尝试类似
model.workflowStatusModel.someMember.subscribe(function (newValue) {
console.debug("Hey, it changed!", newValue);
});