Knockout.js Binding to dropdownlist

16,367

When working with <select> options, the value binding will determine which of the options is selected, usually you'll want an observable in your viewmodel (e.g. selectedTemplate) that this is set to. Then this observable will automatically be mapped to the actual object from the observable array. Setting value: etId doesn't make sense since there's no etId in your root viewmodel.

Example: http://jsfiddle.net/antishok/968Gy/

function EmailTemplateViewModel() {
    var self = this;
    self.ETList = ko.observableArray();
    self.selectedTemplate = ko.observable();
    // ...
}

HTML:

<select data-bind="options: ETList, value:selectedTemplate, optionsText: 'etTitle'" class="dropdown"></select>

You might have intended to to optionsValue: 'etId' which would work but is usually a less preferable approach (because the observable's value would now be set to the ID instead of the actual object)

Share:
16,367
Princa
Author by

Princa

Test Test Test

Updated on June 17, 2022

Comments

  • Princa
    Princa about 2 years

    Trying to bind data to a dropdown list,

        function EmailTemplate(data) {
            var self = this;
            self.etId = ko.observable(data.email_template_id);
            self.etTypeId = ko.observable(data.email_template_type_id);
            self.etTitle = ko.observable(data.email_template_title);
            self.etContent = ko.observable(data.email_template_content);
            self.etAppYear = ko.observable(data.app_year);
            self.etSubject = ko.observable(data.subject);
            self.etActive = ko.observable(data.active);
        }
    
        function EmailTemplateViewModel() {
            var self = this;
            self.ETList = ko.observableArray();
    
            var uri = '/admin/services/EmailTemplateService.svc/EmailTemplates';
            OData.read(uri, function (data, response) {
                $.each(data.results, function (index, item) {
                    self.ETList.push(new EmailTemplate(item));
                });
            });
        }
        $(document).ready(function () {
            ko.applyBindings(new EmailTemplateViewModel());            
        });
    

    HTML markup:

     <select data-bind="options: ETList, value:etId, optionsText: 'etTitle' "class="dropdown"></select>
    

    When I run this I got: Uncaught Error: Unable to parse bindings. Message: ReferenceError: etIdis not defined; Bindings value: options: ETList, value:etId, optionsText: 'etTitle'

    When we bind to drop down list, how should we bind the value? and after binding, how should we capture or create dropdown change event in Knockout?

  • Princa
    Princa about 11 years
    thanks a lot @antishok! etId is not in the root viewmodel, but neither does etTitle. In this case, how should I be able to bind text to etTitle and bind value to etId, so when I change drop down selection, I could get etID instead of etTitle?
  • Princa
    Princa about 11 years
    Ok I got it, I could just say selectedTempalte() && selectedTemplate().etId. So selectedTemplate is an object of binded to option, but showing etTitle as text!!
  • Princa
    Princa about 11 years
    <span data-bind="text: selectedTemplateType() && selectedTemplateType().etId"></span> still don't know why we need to call selectedTempalte() first and then use &&, what's that for?
  • antishok
    antishok about 11 years
    It's needed there because at first there is no item selected, so selectedTemplate() === undefined. it's the same as doing: selectedTemplate() ? selectedTemplate().etId : undefined. Without this we'd get an error for trying to access .etId on undefined
  • Princa
    Princa about 11 years
    yes! Thanks a lot for the explanation. I have another question, the dropdownlist actually is a trigger, once selected changed, then subscribe the selectedTemplate to call a ajax to pull data back, for initial load, it's fine,I bind to a observableArray like self.ETList, but how should I clean this observableArray each time dropdown changes selection and pull back data, now it's keep adding, and if I assign self.ETList = []; after ajax callback but before databind, then i don't get anything...
  • Princa
    Princa about 11 years
    I got it, use removeall() for the array