【问题标题】:Set item name from combobox to knockout list将项目名称从组合框设置为淘汰列表
【发布时间】:2013-02-01 23:19:32
【问题描述】:

我在显示从组合框到淘汰赛列表的值时遇到了一个问题。 请在下面的图片中我从组合框中选择项目。当我从组合框中选择项目时,它会更新具有相同值的所有行。

左侧的列表不存储数据库中组合框中的名称,但它存储 id。所以组合框和列表与称为状态的列相连。在我的 html 中,我定义了如下列表,其中 ChangeControlName 是我要绑定到列表的列表

<tbody data-bind="foreach: versionDataByProduct">

    <tr data-bind="click: $root.EditVersionDetail, css: { selected: isSelected}"   >

        <td data-bind="text: Name "></td>
        <td data-bind="text: Code"></td>
        <td data-bind ="text: PlatformVersionName"></td>
        <td data-bind ="text: ChangeControlName"></td>
      </tr>                 

组合框在我的视图模型中如下加载

     // Load Change Control List
    function loadChangeControlList() {
        $.ajax({
            url: "../RestService/Product/ChangeControlList",
            type: "PUT",
            contentType: 'application/json',
            processData: false,
            error: function (XMLHttpRequest, textStatus, errorThrown) {

            },
            success: function (allData) {
                var mappedChangeControls = $.map(allData, function (item) {

                    return new changeControlList(item);
                });
                self.ChangeControls(mappedChangeControls);

            }
        });
    }

我已将我的组合框绑定在 html 中,如下所示

<td><select id="selModuleType"  data-bind="options: $root.modules,  optionsCaption: 'Please select Module...' , value: $root.editModuleId , optionsText: 'ModuleName'" /></td>

当我选择上图所示左侧的行时,我会选择行。在值 editModuleId 的订阅事件上,我尝试将值分配给选定的行,如下所示。

self.editChangeControl.subscribe(function (value) {
        if (!value) {
            return;
        }

        self.selecteditem().ChangeControlId(value.Status());

        self.selecteditem().ChangeControlName(value.ChangeControl());

    });

在上面的代码中 selecteditem 包含我们选择的行。正如您在上面的代码中看到的,ChangeControlId 是我们从组合框中选择的值的 id,它已正确设置到列表中。但是名称设置不正确。原因是 ChangeControlId 存储在数据库中。 ChangeControlId 是显示这些行的表的一部分。我想要的 ChangeControlName 仅用于显示目的。我应该怎么办?我也尝试使用计算的 observable,但它在列表中显示为“对象对象”。我使用了如下计算的 observable

       this.ChangeControlName = ko.computed({
            read: function () {
                debugger;
                return ko.utils.arrayFirst(self.ChangeControls(), function (item) {
                    if (item.Status() === productVersionId.ChangeControlId()) {
                        return item.ChangeControl();
                    }
                });
            },

            write: function (value) {
                console.log("Value i get " + value);
                return value;
            }
        });

【问题讨论】:

  • 这个有 jsfiddle 或 jsbin 吗?
  • 不,我对此一无所知。但是你明白我的问题吗?
  • 我正在努力关注它。是否要将左侧的更新值保存到数据库中以进行更改控制,同时仍仅在标签中显示描述而不是原始 id?
  • 我只想显示已在组合框中选择的名称。我正确保存了id。只是我无法将列表中的值正确设置为组合框中选择的值
  • 所以当左边的一个项目被选中时,他们改变了右边的框,只是左边的一个选定的行应该改变显示?

标签: javascript knockout.js


【解决方案1】:

你去吧,你的设计让你很难到达你想去的地方。

var VersionModel = function () {
  var self = this;

  self.changeControls = ko.observable([{
    name: "Addressed",
    value: 1
  }, {
    name: "Not Addressed",
    value: 2

  }]);

  console.log(self.changeControls()[0].value);
  self.versionDataByProduct = [{
    Name: "DS",
    Code: "sd",
    PlatformVersionName: "5.5.3",
    ChangeControl: ko.observable(self.changeControls()[0]),
  }, {
    Name: "EF",
    Code: "sd",
    PlatformVersionName: "5.5.3",
    ChangeControl: ko.observable(self.changeControls()[0])
  }];
  self.selected = ko.observable(self.versionDataByProduct[0]);
  self.EditVersionDetail = function (item) {

    self.selected(item);
  };
  self.editModuleId = ko.observable();
  self.modules = [{
    editModuleId: 1,
    ModuleName: "ABW-BP-Batch Input"
  }];

  self.editChangeControl = ko.computed({
    read: function () {
      if (self.selected()) {
          console.log('something selected and editChangeControl is changing');
        return self.selected().ChangeControl();
      }
      return '';
    },
    write: function (value) {
      if (value && value != '') {
          console.log('writing new value');
        self.selected().ChangeControl(value);
      }
    }
  });

}
ko.applyBindings(new VersionModel());

和html:

<table class="floatLeft">
  <thead>
    <tr>
      <th>Version name</th>
      <th>Version Code</th>
      <th>Framework version</th>
      <th>Change control</th>
    </tr>
  </thead>
  <tbody data-bind="foreach: versionDataByProduct">
    <tr data-bind="click: $root.EditVersionDetail, css: { selected: $root.selected() == $data}">
      <td data-bind="text: Name "></td>
      <td data-bind="text: Code"></td>
      <td data-bind="text: PlatformVersionName"></td>
      <td data-bind="text: ChangeControl().name,attr:{'data-value':ChangeControl().value}"></td>
    </tr>
  </tbody>
</table>
<select id="selModuleType" data-bind="options: $root.modules,  optionsCaption: 'Please select Module...' , value: $root.editModuleId , optionsText: 'ModuleName'"></select>
<select id="selfChangeControl" data-bind="options: $root.changeControls,  optionsCaption: 'Please select Change control...' , value: editChangeControl , optionsText: 'name'"></select>

http://jsfiddle.net/2Khk3/4/

【讨论】:

  • 多么完美的例子。你真是大师。希望我能从你身上学到一些东西。你知道有什么更好的方法来实现这一目标吗?
  • 您也可以在这方面提供帮助。过去 3 天我真的很挣扎stackoverflow.com/questions/14611768/issue-with-kendo-combobox
  • 这里有一个问题。在加载时的列表中,您已设置为 ChangeControl:ko.observable(self.changeControls()[0])。这总是选择相似的值。假设我的列表已经保存了不同的值。在我们的小提琴示例中,它将类似于值 1 和值 2。现在发生的情况是,假设我的列表预加载了值 1 和 2,并将列表中的第一个值更改为 2,并尝试选择第一行,然后它设置回 1 . 你明白我的意思了吗?
  • 我加载了你在截图中显示的数据,你会根据你的实际用例加载它。
  • 实际上是因为行 ChangeControl: ko.observable(self.changeControls()[0]) 它加载了第一个值。我该怎么办?
猜你喜欢
  • 2019-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 1970-01-01
  • 2018-08-22
相关资源
最近更新 更多