将缺少的项插入到绑定到ko.bindingHandlers.options的数组中

时间:2014-01-17 10:53:58

标签: knockout.js bindinghandlers

我有以下情况。

示例性JavaScript:

function Foo() {
   this.id = ko.observable("KEY_1"); //Current selected item
   this.list = [{ id: "KEY_2", text: "Two" }, { id: "KEY_3", text: "Three" }]; //All available items
}

ko.applyBindings(new Foo());

这是绑定到带有值和选项bindingHandlers的帮助的HTML选择。

data-bind="value: id, optionsEx: list"

可能当前所选项目未包含在所有可用项目的列表中,因为它已在服务器上删除,并且不应再能够被选中。一些 出于历史原因,实体仍将KEY_1的值设置为id。 我想要的是,如果id的值不再在列表中,它应该被添加到列表中作为在客户端上由bindingHandler称为“已删除”的虚拟条目。

我尝试了以下

ko.bindingHandlers["optionsEx"] = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        var allBindings = allBindingsAccessor(),
            optionsValue = allBindings['optionsValue'],
            value = ko.utils.unwrapObservable(allBindings['value']),
            list;

        if (value) {
            list = //external function searching the list for the item any adding it if missing
            ko.bindingHandlers.options.update(element, function () { return list; }, allBindingsAccessor);
        } else {
            ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor);
        }
    }
};

但这不起作用。任何人都可以给我一个提示来实现这个目标吗?

更新: 我创造了一个jsfiddle。它的curiouse因为代码在jsfiddle中工作但不在我们的开发分支中。我必须检查原因。但也许某人有更好的想法来实现这一功能。

http://jsfiddle.net/philipooo/C46A8/

更新: 我看到bindingHandlers的顺序是关键任务。也许这解决了我的问题。

1 个答案:

答案 0 :(得分:1)

我查看了执行此操作的各种方法,并提出将新值添加到选项中指定的基本列表(如果它不存在)。 Go straight to a fiddle

businessUnitsList: ko.observableArray([{
    id: "a",
    title: "business1"
}, {
    id: "b",
    title: "business2"
}, {
    id: "c",
    title: "business3"
}, {
    id: "d",
    title: "business4"
}]),

基本列表数组必须是observableArray,以便在添加新值时由knockout自动更新,然后触发列表刷新。

用于设置绑定的HTML:

<select data-bind="missingText:'{val} is DELETED',
   options:businessUnits.businessUnitsList,
   optionsText:'title',
   optionsValue:'id', 
   value:businessUnits.currentlySelected">
</select>

“missingText”属性挂钩到绑定处理程序并允许配置文本,以及在文本{val}

中未找到的标记值

在我称之为“missingText”的绑定处理程序中

    ko.bindingHandlers["missingText"] = {

    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bind) {
    var allBindings = allBindingsAccessor(),
        items = allBindings['options'],
        value = ko.utils.unwrapObservable(allBindings['value']),
        valueProperty = ko.utils.unwrapObservable(allBindings['optionsValue']),
        textProperty = ko.utils.unwrapObservable(allBindings['optionsText']),
        missingTextProperty= ko.utils.unwrapObservable(allBindings['missingText']),
        valueSetter = allBindings['value'],
        list
    //we must have the two properties specified
    if (!valueProperty || !textProperty){
        throw ("missingText requires the optionsText and optionsValue property to be provided");   
    }

    if (value) {
        //try and find the currentlySelected value in the list
        var found = ko.utils.arrayFilter(items(), function (item) {
            //we're binding to a particular field for the value
            //so look for that as the value
            return item[valueProperty] == value;
        });

        //if we haven't found it in the list, add it with our missingText text
        if (found.length === 0) {

            var newItem ={};
            newItem[valueProperty]=value;
            //replace token with the value that's missing
            newItem[textProperty]=missingTextProperty.replace('{val}', value);  
        //adding the new item to the items list will trigger the list to refresh
            //and display our new value                
        items.push(newItem);

        }

and here is the fiddle again

希望有帮助吗?