【问题标题】:Breeze/Knockout dropdown causing entity to be modifiedBreeze/Knockout 下拉菜单导致实体被修改
【发布时间】:2013-05-04 02:43:28
【问题描述】:

这是我今天遇到的一个奇怪的问题。我有一个使用 Breeze 和 Knockout 的应用程序。在我的一个页面上,我允许用户编辑和保存项目数据。保存按钮仅在进行更改时启用。为了跟踪更改,我订阅了 propertyChanged 事件。这个页面有很多下拉菜单,这会导致一些问题。这是其中一个下拉菜单的示例。

<div>
    <label for="projQAManager">QA Manager</label>
    <select id="projQAManager" data-bind="options: QAManagers,
                                          optionsText: 'FullName',
                                          optionsValue: 'USERNAME',
                                          optionsCaption: 'None',
                                          value: project().QAManager"></select>
</div>

当 project().QAManager 为 "" 时会出现此问题。加载项目后立即触发 propertyChanged 事件,它显示 QAManager 字段从“”更改为 null。这导致实体相信它已被修改,即使没有真正改变。如果 QAManager 已经为空,则一切正常。我想我可以通过并尝试清理数据库并清除所有带有“”的字段并在必要时将它们设置为 null,但如果可以避免,我宁愿不这样做。

【问题讨论】:

    标签: javascript asp.net knockout.js breeze


    【解决方案1】:

    问题确实在于 KnockoutJS 将值 undefined 分配给列表框的标题,您将其标记为“无”。

    在填充列表框后,KnockoutJS 会检查您选择的值 (project().QAManager) 是否与列表框中列出的任何选项匹配。如果不匹配,则选择带有标题的选项,并因此修改列表框的选定值,从而触发project().QAManager 获取undefined 值。

    摘自options绑定处理程序的文档(重点是我的):

    KO 将在项目列表前面加上一个显示文本的项目 [标题文本] 并具有值 undefined。所以,如果 myChosenValue 保存值 undefined (默认情况下可观察到的),然后 将选择虚拟选项。 如果 optionsCaption 参数是 可观察的,那么初始项目的文本将更新为 observable 的值变化

    我想到了以下解决方法,从最简单到最难,但最“正确”:

    1. 其中一种解决方法是在选项列表 (QAManagers) 中添加一个值为 undefined 的条目,然后再将其作为可观察数组使用。

    2. 为选项编写自定义绑定处理程序,允许为标题项设置给定值,而不是将其设置为undefined。这应该包括复制/粘贴 99% 的 KnockoutJS 的“选项”实现,并且只更改我在选项 3 中编写的代码。

    3. 更改 KnockoutJS 的源代码,以便考虑新的“optionsCaptionValue”绑定,就像这样(我已经修改了原始代码,就像你应该做的那样):

          if (allBindings['optionsCaption']) {
              var option = document.createElement("option");
              ko.utils.setHtml(option, allBindings['optionsCaption']);
      
              var captionsValue;
              if (allBindings['optionsCaptionValue']) {
                 captionsValue = ko.utils.unwrapObservable(allBindings['optionsCaptionValue']);
              }
              ko.selectExtensions.writeValue(option, captionsValue ? captionsValue : undefined);
              element.appendChild(option);
          }
      

    【讨论】:

    • 谢谢,这看起来是个不错的解决方案
    猜你喜欢
    • 2013-08-10
    • 2021-11-20
    • 1970-01-01
    • 2016-12-16
    • 2014-08-03
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 2016-12-11
    相关资源
    最近更新 更多