Javascript Breeze/Knockout下拉列表导致修改实体

Javascript Breeze/Knockout下拉列表导致修改实体,javascript,asp.net,knockout.js,breeze,Javascript,Asp.net,Knockout.js,Breeze,这是我今天遇到的一个有点奇怪的问题。我有一个使用Breeze和Knockout的应用程序。在我的一个页面上,我允许用户编辑和保存项目数据。仅当进行了更改时,“保存”按钮才启用。为了跟踪更改,我订阅了propertyChanged事件。这个页面有相当多的下拉列表,导致了一些问题。下面是其中一个下拉列表的示例 <div> <label for="projQAManager">QA Manager</label> <select id="pro

这是我今天遇到的一个有点奇怪的问题。我有一个使用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,但如果可以避免,我宁愿不这样做。

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

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

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

KO将在项目列表的前面加上显示文本的项目 [标题文本]并具有值未定义。那么,如果myChosenValue 保存未定义的值(默认情况下,可观察对象会这样做),然后 将选择虚拟选项如果optionsCaption参数是 可观察,则初始项的文本将更新为 可观察对象的值发生变化

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

  • 解决方法之一是在选项列表(
    QAManagers
    )中添加一个值未定义的条目,然后将其作为可观察数组使用

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

  • 更改KnockoutJS的源代码,以便考虑新的“optionCaptionValue”绑定,如下所示(我已经像您应该做的那样修改了原始代码):


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

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

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

    KO将在项目列表的前面加上显示文本的项目 [标题文本]并具有值未定义。那么,如果myChosenValue 保存未定义的值(默认情况下,可观察对象会这样做),然后 将选择虚拟选项如果optionsCaption参数是 可观察,则初始项的文本将更新为 可观察对象的值发生变化

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

  • 解决方法之一是在选项列表(
    QAManagers
    )中添加一个值未定义的条目,然后将其作为可观察数组使用

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

  • 更改KnockoutJS的源代码,以便考虑新的“optionCaptionValue”绑定,如下所示(我已经像您应该做的那样修改了原始代码):


  • 谢谢,这看起来是个不错的解决方案谢谢,这看起来是个不错的解决方案
        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);
        }