Knockout过滤了阵列问题

时间:2016-04-27 09:23:31

标签: javascript html ajax knockout.js binding

我有一个包含“设备”数据的表,当用户选择设备时,设备表单已填满。 设备类型下拉列表包含所有设备类型,并自动选择所选设备的设备类型。还有一个设备型号下拉列表,仅显示与所选设备类型相关的型号。当用户从设备列表中选择一个设备时,表单填充良好且一切正常,但我希望当用户从设备中手动选择其他类型的设备时,设备模型下拉列表也会更新下来,这不起作用。

enter image description here

段:

<select data-bind="options: selectedDevice() ? modelsByDeviceType(selectedDevice().DeviceTypeID) : null, optionsText: 'DeviceModelName', optionsValue: 'DeviceModelID', value: selectedDevice() ? selectedDevice().DeviceModelID : 0, optionsCaption: ''"></select>

self.modelsByDeviceType = function (selectedDeviceType) {
      return ko.utils.arrayFilter(self.deviceModels(), function (m) {
        return (m.DeviceTypeID === selectedDeviceType);
      });
    };

完整代码:https://jsfiddle.net/rickhaar/9aLvd3uw/8/

1 个答案:

答案 0 :(得分:1)

您目前正在使用静态数据,您需要将其更改为淘汰可观察量,然后您的值将更新为2路。映射插件可以帮到你:

function vm() {

  var self = this;

  var devicesData = [{
    DeviceID: 1,
    DeviceName: 'DVR1',
    DeviceTypeID: 1,
    DeviceModelID: 1
  }, {
    DeviceID: 2,
    DeviceName: 'DVR2',
    DeviceTypeID: 1,
    DeviceModelID: 2
  }, {
    DeviceID: 3,
    DeviceName: 'Cam1',
    DeviceTypeID: 2,
    DeviceModelID: 3
  }, {
    DeviceID: 4,
    DeviceName: 'Cam2',
    DeviceTypeID: 2,
    DeviceModelID: 4
  }];

  var deviceTypesData = [{
    DeviceTypeID: 1,
    DeviceTypeName: 'DVR'
  }, {
    DeviceTypeID: 2,
    DeviceTypeName: 'Camera'
  }];

  var deviceModelsData = [{
    DeviceModelID: 1,
    DeviceTypeID: 1,
    DeviceModelName: 'BOSH AN 5000'
  }, {
    DeviceModelID: 2,
    DeviceTypeID: 1,
    DeviceModelName: 'Aver NEH1116HN'
  }, {
    DeviceModelID: 3,
    DeviceTypeID: 2,
    DeviceModelName: 'Axis M1054'
  }, {
    DeviceModelID: 4,
    DeviceTypeID: 2,
    DeviceModelName: 'FLIR A65'
  }];

  self.devices = ko.observableArray([]);
  self.deviceTypes = ko.observableArray([]);
  self.deviceModels = ko.observableArray([]);
  self.selectedDevice = ko.observable();

  self.init = function() {
    ko.mapping.fromJS(devicesData, {}, self.devices);
    ko.mapping.fromJS(deviceTypesData, {}, self.deviceTypes);
    ko.mapping.fromJS(deviceModelsData, {}, self.deviceModels);
  };

  self.selectDevice = function(index, item) {
    self.selectedDevice(item);
  };
  self.modelsByDeviceType = function(selectedDeviceType) {
    return ko.utils.arrayFilter(self.deviceModels(), function(m) {
      return (m.DeviceTypeID() === selectedDeviceType());
    });
  };

  self.init();

  return self;
}

ko.applyBindings(vm());
.selectedRow {
  background-color: yellow;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<table id="tblData" class="dataTable" border="1">
  <thead>
    <tr>
      <th>Device ID</th>
      <th>Device Name</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: devices">
    <tr data-bind="click: selectDevice.bind($data, $index()), css: { selectedRow: selectedDevice() === $data }">
      <td data-bind="text: DeviceID"></td>
      <td data-bind="text: DeviceName"></td>
    </tr>
  </tbody>
</table>
<br/>
<table border="0">
  <tbody>
    <tr>
      <td>Name</td>
      <td>
        <input type="text" style="width:80px" data-bind="value: selectedDevice() ? selectedDevice().DeviceName : ''" />
      </td>
    </tr>
    <tr>
      <td>Type</td>
      <td>
        <select data-bind="options: deviceTypes, optionsText: 'DeviceTypeName', optionsValue: 'DeviceTypeID', value: selectedDevice() ? selectedDevice().DeviceTypeID : 0, optionsCaption: ''"></select>
      </td>
    </tr>
    <tr>
      <td>Model</td>
      <td>
        <select data-bind="options: selectedDevice() ? modelsByDeviceType(selectedDevice().DeviceTypeID) : null, optionsText: 'DeviceModelName', optionsValue: 'DeviceModelID', value: selectedDevice() ? selectedDevice().DeviceModelID() : 0, optionsCaption: ''"></select>
      </td>
    </tr>
  </tbody>