Domanda

C'è qualche modo in Knockoutjs Binding dove posso specificare il gruppo di opzioni?qualcosa come follwoing

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

Si prega di rispondere.

È stato utile?

Soluzione

Ho ottenuto la risposta dello stesso, ecco la risposta se qualcuno vuole,

<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>
.

Altri suggerimenti

In molti casi, non hai bisogno delle opzioni stesse per essere osservabili, solo il risultato della selezione. Ecco l'esempio che fa la selezione della contea del Regno Unito.

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;
}
.

Recupererai l'opzione selezionata in ViewModel.Countylist.

Ciò consentirà anche a un segnaposto:

<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 sarebbe in questo formato:

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;
})
.

Questo valore di opzione, potrebbe essere un valore in questa semplice istanza.

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

Ma per un oggetto più complesso $ i dati sarebbero l'opzione migliore.

Prova questo.

(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

sorgente

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top