dataContext 绑定到数据

dataContext binding to data

我试图更好地理解 dataContext 并尝试创建引用文档的 dataContext。

    <xp:this.dataContexts>
      <xp:dataContext var="doc1">
        <xp:this.value>
          <![CDATA[#{javascript:
          var db:NotesDatabase = sessionAsSigner.getDatabase("","privDb.nsf");
          var adoc:NotesDocument = db.createDocument();
          return adoc }]]>
        </xp:this.value>
     </xp:dataContext>
    </xp:this.dataContexts>

然后我尝试使用 EL 和 javascript 将我的 xpage 上的字段绑定到 dataContext

    <xp:inputText id="inputText2" value="#{doc1.lastname}"></xp:inputText>
    <xp:inputText id="inputText1" value="${javascript:doc1.firstname}"></xp:inputText>

但是当我保存时,它并没有保存任何东西。

    <xp:button value="save" id="button1">
        <xp:eventHandler event="onclick" submit="true"
             refreshMode="complete">
                <xp:this.action><![CDATA[#{javascript:
                    print(doc1.getClass().getName() )
                    doc1.save();
                }]]></xp:this.action>
        </xp:eventHandler>
    </xp:button>

显示 class 名称的打印命令显示为 lotus.domino.local.Document

文档已保存到数据库中,但除 $UpdatedBy 外没有其他值。我似乎无法将字段绑定到编辑框。

我走这条路的原因有两个,1.我想使用 sessionAsSigner 这样我就可以将远程数据库 (privDb.nsf) 上的数据库安全性保持在匿名和默认无访问权限,并且2. 我想多了解一点 dataContext、数据源和绑定。我已经阅读了 "easy" 使用 Public 文档的方式,使用 $PublicAccess 字段等,这是 "Old School" Notes 方式,是的,我可以做就是这样,但如果可能的话,想了解如何使用 dataContexts 来做到这一点。

您 运行 遇到的直接问题是,#{} 绑定的 dataContext 会在页面加载期间多次重新评估,而且我相信每次引用它们时都会重新评估。通常,dataContexts 的经验法则(不要误会我的意思——我喜欢它们)是它们要么成本极低,如快速数学计算,要么受 ${} 约束。不过,后者在这里不起作用,因为文档在第一次加载后无法保存。

您可能想尝试的方法是像这样使用 dataContext:

<xp:dataContext var="docData" value="${javascript: new java.util.HashMap() }" />

基本上,用一个简单的物体作为握笔。然后,在保存操作中,创建新文档并在其中设置 "docData" 中的所有值,例如:

var db = sessionAsSigner.getDatabase("", "privDb.nsf");
var doc = db.createDocument();
doc.replaceItemValue("firstname", docData.get("firstname"));
doc.replaceItemValue("lastname", docData.get("lastname"));
doc.save();

这种方法有一些注意事项:

  • 每次保存都会创建一个新文档,而不是编辑现有文档。不过,您可以通过将 UNID 存储回地图并从数据库中获取它来更改此设置
  • 在这种情况下它应该可以正常工作,但您必须注意数据类型。例如,如果您有一个多值控件,那么 XPages 运行时可能会创建一个 ArrayList,除非您使用 OpenNTF Domino API

最后一点,您对名字的绑定几乎肯定不是您想要的。这可能只是您正在进行的测试的产物,但如果我不提及它,那将是我的疏忽。

dataContext 基本上是一个范围变量,范围低于 viewScope 但高于 requestScope,范围为组件。该组件可以是 XPage、自定义控件或面板(是的,dataContexts 也可以添加到面板)。

与页面上的其他作用域变量一样,简单的保存操作不会保存 dataContext。如果您想要一个可创建和可保存的变量,那就是数据对象。它具有特定的 createObject 和 saveObject 属性,您可以在其中定义当它们被 XPages 运行时调用时应该发生什么。

同样,与其他作用域变量一样,它需要序列化,因此您不能在其中存储 Domino 对象。所以你不能在其中存储 NotesDocument。您需要在 NotesDocument 周围包裹一个普通的 Java 对象。随着对 XPages 的更深入理解,dominoDocument 数据源正在做的事情变得显而易见(为文档上的所有字段创建属性,存储其注释 ID、UNID,添加其他属性,例如它是处于编辑模式还是新模式等)。

最后一点,正如 Jesse 所说,dataContexts 在部分刷新期间被重新评估多次。我最近没有重新测试,但在 8.5.3 下,绑定到 XPage 或自定义控件的 dataContexts 比绑定到面板的 dataContexts 被重新评估更多,所以我推荐后者。