dataContext绑定到数据

时间:2015-07-08 23:14:46

标签: xpages xpages-ssjs

我试图更好地理解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>

显示类名的print命令显示为lotus.domino.local.Document

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

我走这条路的原因有两个,1。我想使用sessionAsSigner所以我可以保持远程数据库的安全性(privDb.nsf)在无访问权限为匿名和默认,以及2.我想要学习更多关于dataContext,数据源和绑定的知识。我已经阅读了使用公共文档的“简单”方法,使用$ PublicAccess字段等,这是“老派”笔记方式,是的,我可以这样做,但想要了解如何做到这一点如果可能,使用dataContexts。

2 个答案:

答案 0 :(得分:2)

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

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

同样,与其他范围的变量一样,它需要序列化,因此您无法在其中存储Domino对象。因此,您无法在其中存储NotesDocument。您需要围绕NotesDocument包装普通的Java对象。随着对XPage的更深入了解,很明显dominoDocument数据源正在做什么(为文档上的所有字段创建属性,存储其注释ID,UNID,添加其他属性,例如它是否处于编辑模式或者新的等等。)

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

答案 1 :(得分:1)

您遇到的直接问题是#{} - 绑定的dataContexts会在页面加载期间多次重新评估,并且我相信,每次引用它们时都会如此。一般来说,使用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存储回地图并从数据库中提取来进行更改,但
  • 在这种情况下它应该按原样运行,但您必须注意数据类型。例如,如果您有一个多值控件,那么XPage运行时可能会创建一个ArrayList,除非您使用OpenNTF Domino API,否则必须将其转换为Vector进行存储

作为最后一点,你对firstname的绑定几乎绝对不是你想要的。这可能只是你正在进行的测试的一个神器,但如果我没有提到它,我会失职。