Knockoutjs 使用选项组进行选择

发布于 2024-12-28 06:33:44 字数 182 浏览 0 评论 0原文

Knockoutjs 绑定中有什么方法可以指定 optionsGroup 吗?类似以下内容

<select data-bind="options: collection, optionsText: 'Text', optionsGroup: 'Group'/>

请回复。

Is there any way in Knockoutjs binding where I can specify optionsGroup ? something like follwoing

<select data-bind="options: collection, optionsText: 'Text', optionsGroup: 'Group'/>

Please do reply.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

赠意 2025-01-04 06:33:44

我得到了同样的答案,如果有人想要的话,这就是答案,

<td><select class="fieldValue" data-bind="foreach: $root.AvailableFields, value: FieldId, event :{ change: $root.onFieldSelectionChange}">
        <optgroup data-bind="attr: {label: FieldGroupName}, foreach: Fields">
            <option data-bind="text: HeaderText, value: FieldId"></option>
        </optgroup>
     </select>
  </td>

I got the answer of the same, here is the answer if anybody wants,

<td><select class="fieldValue" data-bind="foreach: $root.AvailableFields, value: FieldId, event :{ change: $root.onFieldSelectionChange}">
        <optgroup data-bind="attr: {label: FieldGroupName}, foreach: Fields">
            <option data-bind="text: HeaderText, value: FieldId"></option>
        </optgroup>
     </select>
  </td>
那伤。 2025-01-04 06:33:44

在许多情况下,您不需要观察选项本身,只需观察选择的结果即可。
这是进行英国县选择的示例。

HTML:

<div class="form-group">
    <label for="county">County</label>
        <select class="fieldValue" data-bind="foreach: $root.countyList, value: orgCounty">
            <optgroup data-bind="attr: {label: label}, foreach: counties">
            <option data-bind="text: label, value: label"></option>
            </optgroup>
        </select>
</div>

JS:

viewModel.countyList = getCountyList();
viewModel.orgCounty = ko.observable('London'); // Put default value here

function getCountyList() {
    var $arrayCounties = [
        { "label" : "England", "counties" : [ 
            { "label" : "Bedfordshire"},
            { "label" : "Berkshire"},
            { "label" : "Bristol"},
            { "label" : "Buckinghamshire"},
            { "label" : "Cambridgeshire"},
            { "label" : "Cheshire"},
            { "label" : "City of London"},
            { "label" : "Cornwall"},
            { "label" : "Cumbria"},
            { "label" : "Derbyshire"},
            { "label" : "Devon"},
            { "label" : "Dorset"},
            { "label" : "Durham"},
            { "label" : "East Riding of Yorkshire"},
            { "label" : "East Sussex"},
            { "label" : "Essex"},
            { "label" : "Gloucestershire"},
            { "label" : "Greater London"},
            { "label" : "Greater Manchester"},
            { "label" : "Hampshire"},
            { "label" : "Herefordshire"},
            { "label" : "Hertfordshire"},
            { "label" : "Isle of Wight"},
            { "label" : "Kent"},
            { "label" : "Lancashire"},
            { "label" : "Leicestershire"},
            { "label" : "Lincolnshire"},
            { "label" : "Merseyside"},
            { "label" : "Norfolk"},
            { "label" : "North Yorkshire"},
            { "label" : "Northamptonshire"},
            { "label" : "Northumberland"},
            { "label" : "Nottinghamshire"},
            { "label" : "Oxfordshire"},
            { "label" : "Rutland"},
            { "label" : "Shropshire"},
            { "label" : "Somerset"},
            { "label" : "South Yorkshire"},
            { "label" : "Staffordshire"},
            { "label" : "Suffolk"},
            { "label" : "Surrey"},
            { "label" : "Tyne and Wear"},
            { "label" : "Warwickshire"},
            { "label" : "West Midlands"},
            { "label" : "West Sussex"},
            { "label" : "West Yorkshire"},
            { "label" : "Wiltshire"},
            { "label" : "Worcestershire"} ]},
        { "label" : "Wales", "counties" : [ 
            { "label" : "Anglesey"},
            { "label" : "Brecknockshire"},
            { "label" : "Caernarfonshire"},
            { "label" : "Carmarthenshire"},
            { "label" : "Cardiganshire"},
            { "label" : "Denbighshire"},
            { "label" : "Flintshire"},
            { "label" : "Glamorgan"},
            { "label" : "Merioneth"},
            { "label" : "Monmouthshire"},
            { "label" : "Montgomeryshire"},
            { "label" : "Pembrokeshire"},
            { "label" : "Radnorshire"} ]},
        { "label" : "Scotland", "counties" : [ 
            { "label" : "Aberdeenshire"},
            { "label" : "Angus"},
            { "label" : "Argyllshire"},
            { "label" : "Ayrshire"},
            { "label" : "Banffshire"},
            { "label" : "Berwickshire"},
            { "label" : "Buteshire"},
            { "label" : "Cromartyshire"},
            { "label" : "Caithness"},
            { "label" : "Clackmannanshire"},
            { "label" : "Dumfriesshire"},
            { "label" : "Dunbartonshire"},
            { "label" : "East Lothian"},
            { "label" : "Fife"},
            { "label" : "Inverness-shire"},
            { "label" : "Kincardineshire"},
            { "label" : "Kinross"},
            { "label" : "Kirkcudbrightshire"},
            { "label" : "Lanarkshire"},
            { "label" : "Midlothian"},
            { "label" : "Morayshire"},
            { "label" : "Nairnshire"},
            { "label" : "Orkney"},
            { "label" : "Peeblesshire"},
            { "label" : "Perthshire"},
            { "label" : "Renfrewshire"},
            { "label" : "Ross-shire"},
            { "label" : "Roxburghshire"},
            { "label" : "Selkirkshire"},
            { "label" : "Shetland"},
            { "label" : "Stirlingshire"},
            { "label" : "Sutherland"},
            { "label" : "West Lothian"},
            { "label" : "Wigtownshire"} ]},
        { "label" : "Northern Ireland", "counties" : [ 
            { "label" : "Antrim"},
            { "label" : "Armagh"},
            { "label" : "Down"},
            { "label" : "Fermanagh"},
            { "label" : "Londonderry"},
            { "label" : "Tyrone"} ]}
        ];

    return $arrayCounties;
}

您将在 viewModel.countyList 中检索所选选项。

In many cases, you don't need the options themselves to be observable, just the result of the selection.
Here is the example which does UK county selection.

HTML:

<div class="form-group">
    <label for="county">County</label>
        <select class="fieldValue" data-bind="foreach: $root.countyList, value: orgCounty">
            <optgroup data-bind="attr: {label: label}, foreach: counties">
            <option data-bind="text: label, value: label"></option>
            </optgroup>
        </select>
</div>

JS :

viewModel.countyList = getCountyList();
viewModel.orgCounty = ko.observable('London'); // Put default value here

function getCountyList() {
    var $arrayCounties = [
        { "label" : "England", "counties" : [ 
            { "label" : "Bedfordshire"},
            { "label" : "Berkshire"},
            { "label" : "Bristol"},
            { "label" : "Buckinghamshire"},
            { "label" : "Cambridgeshire"},
            { "label" : "Cheshire"},
            { "label" : "City of London"},
            { "label" : "Cornwall"},
            { "label" : "Cumbria"},
            { "label" : "Derbyshire"},
            { "label" : "Devon"},
            { "label" : "Dorset"},
            { "label" : "Durham"},
            { "label" : "East Riding of Yorkshire"},
            { "label" : "East Sussex"},
            { "label" : "Essex"},
            { "label" : "Gloucestershire"},
            { "label" : "Greater London"},
            { "label" : "Greater Manchester"},
            { "label" : "Hampshire"},
            { "label" : "Herefordshire"},
            { "label" : "Hertfordshire"},
            { "label" : "Isle of Wight"},
            { "label" : "Kent"},
            { "label" : "Lancashire"},
            { "label" : "Leicestershire"},
            { "label" : "Lincolnshire"},
            { "label" : "Merseyside"},
            { "label" : "Norfolk"},
            { "label" : "North Yorkshire"},
            { "label" : "Northamptonshire"},
            { "label" : "Northumberland"},
            { "label" : "Nottinghamshire"},
            { "label" : "Oxfordshire"},
            { "label" : "Rutland"},
            { "label" : "Shropshire"},
            { "label" : "Somerset"},
            { "label" : "South Yorkshire"},
            { "label" : "Staffordshire"},
            { "label" : "Suffolk"},
            { "label" : "Surrey"},
            { "label" : "Tyne and Wear"},
            { "label" : "Warwickshire"},
            { "label" : "West Midlands"},
            { "label" : "West Sussex"},
            { "label" : "West Yorkshire"},
            { "label" : "Wiltshire"},
            { "label" : "Worcestershire"} ]},
        { "label" : "Wales", "counties" : [ 
            { "label" : "Anglesey"},
            { "label" : "Brecknockshire"},
            { "label" : "Caernarfonshire"},
            { "label" : "Carmarthenshire"},
            { "label" : "Cardiganshire"},
            { "label" : "Denbighshire"},
            { "label" : "Flintshire"},
            { "label" : "Glamorgan"},
            { "label" : "Merioneth"},
            { "label" : "Monmouthshire"},
            { "label" : "Montgomeryshire"},
            { "label" : "Pembrokeshire"},
            { "label" : "Radnorshire"} ]},
        { "label" : "Scotland", "counties" : [ 
            { "label" : "Aberdeenshire"},
            { "label" : "Angus"},
            { "label" : "Argyllshire"},
            { "label" : "Ayrshire"},
            { "label" : "Banffshire"},
            { "label" : "Berwickshire"},
            { "label" : "Buteshire"},
            { "label" : "Cromartyshire"},
            { "label" : "Caithness"},
            { "label" : "Clackmannanshire"},
            { "label" : "Dumfriesshire"},
            { "label" : "Dunbartonshire"},
            { "label" : "East Lothian"},
            { "label" : "Fife"},
            { "label" : "Inverness-shire"},
            { "label" : "Kincardineshire"},
            { "label" : "Kinross"},
            { "label" : "Kirkcudbrightshire"},
            { "label" : "Lanarkshire"},
            { "label" : "Midlothian"},
            { "label" : "Morayshire"},
            { "label" : "Nairnshire"},
            { "label" : "Orkney"},
            { "label" : "Peeblesshire"},
            { "label" : "Perthshire"},
            { "label" : "Renfrewshire"},
            { "label" : "Ross-shire"},
            { "label" : "Roxburghshire"},
            { "label" : "Selkirkshire"},
            { "label" : "Shetland"},
            { "label" : "Stirlingshire"},
            { "label" : "Sutherland"},
            { "label" : "West Lothian"},
            { "label" : "Wigtownshire"} ]},
        { "label" : "Northern Ireland", "counties" : [ 
            { "label" : "Antrim"},
            { "label" : "Armagh"},
            { "label" : "Down"},
            { "label" : "Fermanagh"},
            { "label" : "Londonderry"},
            { "label" : "Tyrone"} ]}
        ];

    return $arrayCounties;
}

You will retrieve the selected option in viewModel.countyList.

不交电费瞎发啥光 2025-01-04 06:33:44

这也将允许占位符:

<select class="form-control needsclick" data-bind="value: Value">
  <option value="" disabled selected>Select Value...</option>
  <!-- ko foreach: Group -->
    <optgroup data-bind="attr: { label: Label }, foreach: Collection">
      <option data-bind="text: Label, value: $data"></option>
    </optgroup>
  <!-- /ko -->
</select>

JS 将采用以下格式:

self.Group = ko.pauseableComputed(function () {
   var groups = [
     { 
       Label: 'Group 1',
       Collection: [
          { Label: 'Data 1', Value: 'Data 1' },
          { Label: 'Data 2', Value: 'Data 2' },
       ]
     },
     { 
       Label: 'Group 2',
       Collection: [
          { Label: 'Data 3', Value: 'Data 3' },
          { Label: 'Data 4', Value: 'Data 4' },
       ]
     },
   ]
   return groups;
})

此选项值,可以是这个简单实例中的值。

<option data-bind="text: Label, value: Value"></option>

但对于更复杂的对象 $data 将是更好的选择。

This will also allow a placeholder:

<select class="form-control needsclick" data-bind="value: Value">
  <option value="" disabled selected>Select Value...</option>
  <!-- ko foreach: Group -->
    <optgroup data-bind="attr: { label: Label }, foreach: Collection">
      <option data-bind="text: Label, value: $data"></option>
    </optgroup>
  <!-- /ko -->
</select>

JS would be in this format:

self.Group = ko.pauseableComputed(function () {
   var groups = [
     { 
       Label: 'Group 1',
       Collection: [
          { Label: 'Data 1', Value: 'Data 1' },
          { Label: 'Data 2', Value: 'Data 2' },
       ]
     },
     { 
       Label: 'Group 2',
       Collection: [
          { Label: 'Data 3', Value: 'Data 3' },
          { Label: 'Data 4', Value: 'Data 4' },
       ]
     },
   ]
   return groups;
})

This option value, could be value in this simple instance.

<option data-bind="text: Label, value: Value"></option>

But for more complex object $data would be the better option.

花间憩 2025-01-04 06:33:44

试试这个。

(function () {
ko.bindingHandlers["groupedOptions"] = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        if (element.tagName != "SELECT")
            throw new Error("groupedOptions binding applies only to SELECT elements");

        var previousSelectedValues = [];
        for (var i = 0; i < element.childNodes.length; i++) {
            var node = element.childNodes[i];
            if (node.tagName == "OPTGROUP") {
                if (node.childNodes != undefined) {
                    for (var k = 0; k < node.childNodes.length; k++) {
                        var childNode = node.childNodes[k];
                        if (childNode.tagName && childNode.tagName && childNode.tagName == "OPTION" && childNode.selected) {
                            previousSelectedValues.push(ko.selectExtensions.readValue(childNode));
                        }
                    }
                }
            } else if (node.tagName && node.tagName == "OPTION" && node.selected) {
                previousSelectedValues.push(ko.selectExtensions.readValue(node));
            }
        }

        var previousScrollTop = element.scrollTop;

        var value = ko.utils.unwrapObservable(valueAccessor());

        // Clear existing elements
        element.innerHTML = "";

        if (value) {
            var allBindings = allBindingsAccessor();
            if (typeof value.length != "number")
                value = [value];
            if (allBindings['optionsCaption']) {
                var option = document.createElement("OPTION");
                option.innerHTML = allBindings['optionsCaption'];
                ko.selectExtensions.writeValue(option, undefined);
                element.appendChild(option);
            }

            var optionsGroupNamesValue = allBindings['optionsGroupNames'];

            // Group values into optgroups
            var groupedOptions = [];
            var optionsGroupValue = allBindings['optionsGroup']; // undefined if not given
            for (var i = 0, j = value.length; i < j; i++) {
                var optionsGroup = null;
                if (typeof optionsGroupValue == "function")
                    optionsGroup = optionsGroupValue(value[i]);
                else if (typeof optionsGroupValue == "string")
                    optionsGroup = value[i][optionsGroupValue];
                else
                    optionsGroup = "";
                if (typeof groupedOptions[optionsGroup] == "undefined")
                    groupedOptions[optionsGroup] = [];

                groupedOptions[optionsGroup].push(value[i]);
            }

            // Create HTML elements
            for (var groupName in groupedOptions) {
                var optgroup = null;
                // Add an OPTGROUP for all groups except for ""
                if (groupName != "") {
                    optgroup = document.createElement("OPTGROUP");
                    optgroup.label = groupName;
                    element.appendChild(optgroup);
                }

                // Create HTML elements for options within this group
                for (var i = 0, j = groupedOptions[groupName].length; i < j; i++) {
                    var valueGroup = groupedOptions[groupName];
                    var option = document.createElement("OPTION");
                    var optionValue = typeof allBindings['optionsValue'] == "string" ? valueGroup[i][allBindings['optionsValue']] : valueGroup[groupName][i];

                    // Pick some text to appear in the drop-down list for this data value
                    var optionsTextValue = allBindings['optionsText'];
                    if (typeof optionsTextValue == "function")
                        optionText = optionsTextValue(valueGroup[i]); // Given a function; run it against the data value
                    else if (typeof optionsTextValue == "string")
                        optionText = valueGroup[i][optionsTextValue]; // Given a string; treat it as a property name on the data value
                    else
                        optionText = optionValue; // Given no optionsText arg; use the data value itself

                    optionValue = ko.utils.unwrapObservable(optionValue);
                    optionText = ko.utils.unwrapObservable(optionText);
                    ko.selectExtensions.writeValue(option, optionValue);

                    option.innerHTML = optionText.toString();

                    if (optgroup != null)
                        optgroup.appendChild(option);
                    else
                        element.appendChild(option);
                }
            }

            // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.
            // That's why we first added them without selection. Now it's time to set the selection.
            var newOptions = element.getElementsByTagName("OPTION");
            var countSelectionsRetained = 0;

            for (var i = 0, j = newOptions.length; i < j; i++) {
                if (ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[i])) >= 0) {
                    ko.utils.setOptionNodeSelectionState(newOptions[i], true);
                    countSelectionsRetained++;
                }
            }

            if (previousScrollTop)
                element.scrollTop = previousScrollTop;
        }
    }
};

ko.bindingHandlers['selectedOptions'] = {
    getSelectedValuesFromSelectNode: function (selectNode) {
        var result = [];
        var nodes = selectNode.childNodes;
        for (var i = 0, j = nodes.length; i < j; i++) {
            var node = nodes[i];
            if ((node.tagName == "OPTGROUP") && node.childNodes != null) {
                var subResult = this.getSelectedValuesFromSelectNode(node);
                for (var k = 0; k < subResult.length; k++) {
                    result.push(subResult[k]);
                }
            }
            else {
                if ((node.tagName == "OPTION") && node.selected)
                    result.push(ko.selectExtensions.readValue(node));
            }
        }

        return result;
    },
    setSelectedValuesFromSelectNode: function (selectNode, newValue) {
        var nodes = selectNode.childNodes;
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            if (node.tagName == "OPTION") {
                ko.utils.setOptionNodeSelectionState(node, ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0);
            }
            else if (node.tagName == "OPTGROUP") {
                for (var k = 0; k < node.childNodes.length; k++) {
                    var childNode = node.childNodes[k];
                    if (childNode.tagName && childNode.tagName == "OPTION") {
                        ko.utils.setOptionNodeSelectionState(childNode, ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(childNode)) >= 0);
                    }
                }
            }
        }
    },
    'init': function (element, valueAccessor, allBindingsAccessor) {
        ko.utils.registerEventHandler(element, "change", function () {
            var value = valueAccessor();
            if (ko.isWriteableObservable(value))
                value(ko.bindingHandlers['selectedOptions'].getSelectedValuesFromSelectNode(this));
            else {
                var allBindings = allBindingsAccessor();
                if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['value'])
                    allBindings['_ko_property_writers']['value'](ko.bindingHandlers['selectedOptions'].getSelectedValuesFromSelectNode(this));
            }
        });
    },
    'update': function (element, valueAccessor) {
        if (element.tagName != "SELECT")
            throw new Error("values binding applies only to SELECT elements");

        var newValue = ko.utils.unwrapObservable(valueAccessor());
        if (newValue && typeof newValue.length == "number") {
            ko.bindingHandlers['selectedOptions'].setSelectedValuesFromSelectNode(element, newValue);
        }
    }
};
})();



<select data-bind="groupedOptions: collection, optionsText: 'Text', optionsValue: 'Value', optionsGroup: 'Group', selectedOptions: Selected"></select>

jsfiddle

来源

Try this.

(function () {
ko.bindingHandlers["groupedOptions"] = {
    update: function (element, valueAccessor, allBindingsAccessor) {
        if (element.tagName != "SELECT")
            throw new Error("groupedOptions binding applies only to SELECT elements");

        var previousSelectedValues = [];
        for (var i = 0; i < element.childNodes.length; i++) {
            var node = element.childNodes[i];
            if (node.tagName == "OPTGROUP") {
                if (node.childNodes != undefined) {
                    for (var k = 0; k < node.childNodes.length; k++) {
                        var childNode = node.childNodes[k];
                        if (childNode.tagName && childNode.tagName && childNode.tagName == "OPTION" && childNode.selected) {
                            previousSelectedValues.push(ko.selectExtensions.readValue(childNode));
                        }
                    }
                }
            } else if (node.tagName && node.tagName == "OPTION" && node.selected) {
                previousSelectedValues.push(ko.selectExtensions.readValue(node));
            }
        }

        var previousScrollTop = element.scrollTop;

        var value = ko.utils.unwrapObservable(valueAccessor());

        // Clear existing elements
        element.innerHTML = "";

        if (value) {
            var allBindings = allBindingsAccessor();
            if (typeof value.length != "number")
                value = [value];
            if (allBindings['optionsCaption']) {
                var option = document.createElement("OPTION");
                option.innerHTML = allBindings['optionsCaption'];
                ko.selectExtensions.writeValue(option, undefined);
                element.appendChild(option);
            }

            var optionsGroupNamesValue = allBindings['optionsGroupNames'];

            // Group values into optgroups
            var groupedOptions = [];
            var optionsGroupValue = allBindings['optionsGroup']; // undefined if not given
            for (var i = 0, j = value.length; i < j; i++) {
                var optionsGroup = null;
                if (typeof optionsGroupValue == "function")
                    optionsGroup = optionsGroupValue(value[i]);
                else if (typeof optionsGroupValue == "string")
                    optionsGroup = value[i][optionsGroupValue];
                else
                    optionsGroup = "";
                if (typeof groupedOptions[optionsGroup] == "undefined")
                    groupedOptions[optionsGroup] = [];

                groupedOptions[optionsGroup].push(value[i]);
            }

            // Create HTML elements
            for (var groupName in groupedOptions) {
                var optgroup = null;
                // Add an OPTGROUP for all groups except for ""
                if (groupName != "") {
                    optgroup = document.createElement("OPTGROUP");
                    optgroup.label = groupName;
                    element.appendChild(optgroup);
                }

                // Create HTML elements for options within this group
                for (var i = 0, j = groupedOptions[groupName].length; i < j; i++) {
                    var valueGroup = groupedOptions[groupName];
                    var option = document.createElement("OPTION");
                    var optionValue = typeof allBindings['optionsValue'] == "string" ? valueGroup[i][allBindings['optionsValue']] : valueGroup[groupName][i];

                    // Pick some text to appear in the drop-down list for this data value
                    var optionsTextValue = allBindings['optionsText'];
                    if (typeof optionsTextValue == "function")
                        optionText = optionsTextValue(valueGroup[i]); // Given a function; run it against the data value
                    else if (typeof optionsTextValue == "string")
                        optionText = valueGroup[i][optionsTextValue]; // Given a string; treat it as a property name on the data value
                    else
                        optionText = optionValue; // Given no optionsText arg; use the data value itself

                    optionValue = ko.utils.unwrapObservable(optionValue);
                    optionText = ko.utils.unwrapObservable(optionText);
                    ko.selectExtensions.writeValue(option, optionValue);

                    option.innerHTML = optionText.toString();

                    if (optgroup != null)
                        optgroup.appendChild(option);
                    else
                        element.appendChild(option);
                }
            }

            // IE6 doesn't like us to assign selection to OPTION nodes before they're added to the document.
            // That's why we first added them without selection. Now it's time to set the selection.
            var newOptions = element.getElementsByTagName("OPTION");
            var countSelectionsRetained = 0;

            for (var i = 0, j = newOptions.length; i < j; i++) {
                if (ko.utils.arrayIndexOf(previousSelectedValues, ko.selectExtensions.readValue(newOptions[i])) >= 0) {
                    ko.utils.setOptionNodeSelectionState(newOptions[i], true);
                    countSelectionsRetained++;
                }
            }

            if (previousScrollTop)
                element.scrollTop = previousScrollTop;
        }
    }
};

ko.bindingHandlers['selectedOptions'] = {
    getSelectedValuesFromSelectNode: function (selectNode) {
        var result = [];
        var nodes = selectNode.childNodes;
        for (var i = 0, j = nodes.length; i < j; i++) {
            var node = nodes[i];
            if ((node.tagName == "OPTGROUP") && node.childNodes != null) {
                var subResult = this.getSelectedValuesFromSelectNode(node);
                for (var k = 0; k < subResult.length; k++) {
                    result.push(subResult[k]);
                }
            }
            else {
                if ((node.tagName == "OPTION") && node.selected)
                    result.push(ko.selectExtensions.readValue(node));
            }
        }

        return result;
    },
    setSelectedValuesFromSelectNode: function (selectNode, newValue) {
        var nodes = selectNode.childNodes;
        for (var i = 0; i < nodes.length; i++) {
            var node = nodes[i];
            if (node.tagName == "OPTION") {
                ko.utils.setOptionNodeSelectionState(node, ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(node)) >= 0);
            }
            else if (node.tagName == "OPTGROUP") {
                for (var k = 0; k < node.childNodes.length; k++) {
                    var childNode = node.childNodes[k];
                    if (childNode.tagName && childNode.tagName == "OPTION") {
                        ko.utils.setOptionNodeSelectionState(childNode, ko.utils.arrayIndexOf(newValue, ko.selectExtensions.readValue(childNode)) >= 0);
                    }
                }
            }
        }
    },
    'init': function (element, valueAccessor, allBindingsAccessor) {
        ko.utils.registerEventHandler(element, "change", function () {
            var value = valueAccessor();
            if (ko.isWriteableObservable(value))
                value(ko.bindingHandlers['selectedOptions'].getSelectedValuesFromSelectNode(this));
            else {
                var allBindings = allBindingsAccessor();
                if (allBindings['_ko_property_writers'] && allBindings['_ko_property_writers']['value'])
                    allBindings['_ko_property_writers']['value'](ko.bindingHandlers['selectedOptions'].getSelectedValuesFromSelectNode(this));
            }
        });
    },
    'update': function (element, valueAccessor) {
        if (element.tagName != "SELECT")
            throw new Error("values binding applies only to SELECT elements");

        var newValue = ko.utils.unwrapObservable(valueAccessor());
        if (newValue && typeof newValue.length == "number") {
            ko.bindingHandlers['selectedOptions'].setSelectedValuesFromSelectNode(element, newValue);
        }
    }
};
})();



<select data-bind="groupedOptions: collection, optionsText: 'Text', optionsValue: 'Value', optionsGroup: 'Group', selectedOptions: Selected"></select>

jsfiddle

source

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文