在knockout.js级联下拉列表

时间:2018-04-10 17:54:54

标签: javascript knockout.js asp.net-mvc-5

我试图从下拉列表中填充另一个下拉列表,我一直收到错误" TypeError:无法处理绑定"值:function(){return CompanySelected}"和" http://localhost/xxx/api/Transaction/LoadInsurancePolicies/undefined 400(错误请求)"。选择保险公司时,必须填写保险单。这是下面的代码

  self.InsuranceCompanyId = ko.observable();
  self._companySelected= ko.observable(null);
  self.CompanySelected = ko.computed({
  read:  function () {return this._companySelected()  },
  write: function (value) {
  $.ajax({
         url: baseUrl + 'api/Transaction/LoadInsurancePolicies/' + 
         value.InsuranceCompanyId,
         type: 'GET',
         headers: { 'Access-Control-Allow-Origin': '*' },
         dataType: 'json',
         success: function (data) {
         if (data.Successfull == 1) 
         {
         self.AllPolicies(data.Model); } },
         error: function (request, error) {                
         }
        });

        this._companySelected(value);
    },
    owner: this     
    });
    self.AllInsuranceCompanies = ko.observableArray([]);
    self.AllPolicies = ko.observableArray([]);
    self.LoadInsuranceCompanies = function () {

    $.ajax({

        url: baseUrl + 'api/Transaction/LoadInsuranceCompanies',
        type: 'GET',
        headers: { 'Access-Control-Allow-Origin': '*' },
        dataType: 'json',
        success: function (data) {
            // console.log(data);
            if (data.Successfull == 1) {
                self.AllInsuranceCompanies(data.Model);
                console.log(data);
            }

        },
        error: function (request, error) {
            console.log(error);
        }
    });
  }
 self.LoadInsuranceCompanies();

 this is my view

  <div class="form-group" data-bind="visible:(InputOption()==0)">
  <label for="InputTxt" class="control-label col-md-4">Insurance 
  Company</label>
  <div class="col-md-8">
  <select data-bind="options: AllInsuranceCompanies,
                  optionsText: 'Name',
                  optionsValue:'Id',
                  optionsCaption: 'Choose...',
                  value:CompanySelected,
                  valueUpdate:'change'"  class="form-control">
                  </select>
                   </div>
                   </div>
  <div class="form-group" data-bind="visible: (InputOption()==0)">
  <label for="InputTxt" class="control-label col-md- 
  4">InsurancePolicy</label>
  <div class="col-md-8">
  <select data-bind="options: AllPolicies,
                    optionsText: 'Name',
                    optionsValue:'Id',
                    value: selectedPolicy,
                    optionsCaption: 'Choose...'" class="form-control"> 
 </select>
 </div>
 </div>

2 个答案:

答案 0 :(得分:2)

以下可能是代码中的问题。

  1. self.CompanySelectedself.AllPolicies之前定义。这将导致运行时错误,因为ko.computed在定义时会自动运行。这是基于淘汰文档。解决方案:尝试在ko.observable之前定义所有ko.computed或在self.AllPolicies之前至少定义self.CompanySelected
  2. 由于ko.computed自动投放,且self.CompanySelected的值为undefined,您的api通话中也会有undefined InsuranceCompanyId将导致错误请求400.解决方案:尝试在调用api之前添加一个警卫。如果(值){....}
  3. 在你的html绑定中,你放了optionsValue: 'Id'。这将导致敲门尝试在模型中找到可能不存在的Id属性。解决方案:从绑定中删除optionsValue:'Id',以便更改选项时的值将是模型对象本身,而不仅仅是Id
  4. 以下是一个示例小提琴:https://jsfiddle.net/przquhcf/1/,它实现了上述解决方案。 注意:我只是用setTimeout代替你的api调用,因为我无法访问它们。不要担心这部分。

答案 1 :(得分:0)

你的解决方案给了我一个想法。我传递了一个函数(值),该值将是所选的Id,将其作为参数添加到api中,它会得到结果。

self.insuranceCompanyId = ko.observable('');
self.selectedPolicy = ko.observable();  
self._companySelected = ko.observable();
self.CompanySelected = ko.pureComputed({
    read: function () {

        return this._companySelected()
    },

    write: function (value) {
        console.log("inside write", value)

        if (value) {
            console.log('data');
            $.ajax({

                url: baseUrl + "api/Transaction/LoadInsurancePolicies/" + 
                value,
                type: 'GET',
                headers: { 'Access-Control-Allow-Origin': '*' },
                dataType: 'json',
                success: function (data) {

                    if (data.Successfull == 1) {
                        self.AllPolicies(data.Model);
                        console.log(value);
                    }

                },
                error: function (request, error) {
                    console.log(error);
                }
            });
            this._companySelected(value);
        }

    },

    owner: this

});
self.LoadInsuranceCompanies();