2013-05-09 79 views
1

这是我今天遇到的一个奇怪问题。我有一个使用Breeze和Knockout的应用程序。在我的一个页面上,我允许用户编辑和保存项目数据。保存按钮仅在更改后才能使用。要跟踪我订阅propertyChanged事件的更改。这个页面有很多下拉菜单会导致一些问题。以下是其中一个下拉列表的示例。Breeze/Knockout dropdown导致实体被修改

<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字段从“”更改为空。这导致实体相信它已被修改,即使没有真正改变。如果QAManager已经为空,那么一切正常。我想我可以通过并尝试清理数据库,并用“”清除任何字段,如果必须将其设置为空,但如果可以避免,我宁愿不要。

回答

1

问题的确在于KnockoutJS将值undefined赋值给标记为“无”的列表框的标题。

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

节选(重点煤矿):

KO将前缀的项目列表中的一个显示文本 [字幕文本],其值为不确定 。因此,如果myChosenValue 包含未定义的值(默认情况下为可观察值),则将选择 虚拟选项。 如果optionsCaption参数为 observable,则初始项目的文本将会更新为 可观察值的更改

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

  1. 其中一个解决方法将是添加到您的选项列表(QAManagers)的在它作为可观察数组提供之前,其值为未定义的条目。

  2. 编写一个自定义绑定处理程序,用于允许为标题项设置给定值的选项,而不是将其设置为undefined。这应该包括在复制/粘贴的KnockoutJS的实现的“选项” 99%,而只是改变我的选项写的代码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); 
        } 
    
+0

谢谢,这看起来像一个很好的解决方案 – OriginalMoose 2013-05-09 16:50:21

相关问题