2013-04-22 73 views
4

在采购订单模块中,我们需要根据采购订单的来源选择方法,竞争类型和总成本提出一些问题。这些问题可能会随着时间以及数据库的不同实例而改变。重复控制内的动态绑定

所以我有一个包含问题的视图,以便我可以动态添加问题到我的XPage,而无需更改代码。每个问题的答案将存储在一个字段中。因此,包含该问题的文档有一个名为FieldName的字段,用于提供将要使用的字段名称。不幸的是,我无法将这些动态字段绑定到文档。

<xp:this.data> 
    <xp:dominoView var="competitionQuestionView" 
     viewName="CompetitionQuestions"> 
    </xp:dominoView> 
</xp:this.data> 
<xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" 
    value="#{competitionQuestionView}"> 
    <xp:label id="label1"> 
     <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]></xp:this.value> 
    </xp:label> 
    <xp:inputText id="inputText1"> 
     <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> 
     <xp:this.value><![CDATA[#{javascript:poDoc[rowData.getColumnValue ("FieldName")];}]]></xp:this.value> 
    </xp:inputText> 
</xp:repeat> 

我已经想尽各种办法要做到这一点,包括制作dynamicInputText自定义控件中的字段名通过,但没有运气。我得到的最接近是,当我用这个:

<xp:this.value> 
<![CDATA[#{javascript:tmp = rowData.getColumnValue ("FieldName");'#{poDoc.'+tmp+'}';}]]> 
</xp:this.value> 

这给了我像#{} poDoc.justification,这是我想要的东西传递给“绑定”,但它结束了作为显示文本值。

我曾尝试使用$来计算加载时的值,但我猜测它没有工作,因为我的(和rowData)视图在加载时不可用。当我想要使用部分刷新时,最终会出现问题,这是由于我想要显示的字段的标准的更新。

其他问题的答案看起来很有希望,但没有提供任何代码,所以我无法弄清楚。

回答

10

在幕后,所有数据源都使用方法getValuesetValue(分别)读取和写入数据。对于Domino文档数据源,表达式#{currentDocument.fieldName}会在运行时转换为currentDocument.getValue('fieldName')currentDocument.setValue('fieldName', postedValue),具体取决于当前操作是读取还是写入。

如果您将其他可编辑组件的value属性设置为SSJS值绑定,那么它不能执行此自动转换......因此它只是将每个操作视为读取操作。

换句话说,为了读/写起作用,它必须是“无前缀”表达式。

有几种处理方法,但最简单的方法是使用数据上下文将SSJS表达式映射到单个变量。数据上下文可以连接到视图根或面板,所以在你的榜样,你会想包装在面板的重复内容:

<xp:repeat id="repeat2" rows="30" var="rowData" style="width:700px" 
    value="#{competitionQuestionView}"> 
    <xp:panel> 
     <xp:this.dataContexts> 
      <xp:dataContext var="fieldName"> 
       <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue ("FieldName");}]]></xp:this.value> 
      </xp:dataContext> 
     </xp:this.dataContexts> 
     <xp:label id="label1"> 
      <xp:this.value><![CDATA[#{javascript:rowData.getColumnValue("Question");}]]>  </xp:this.value> 
     </xp:label> 
     <xp:inputText id="inputText1" value="#{poDoc[fieldName]}"> 
      <xp:this.rendered><![CDATA[#{javascript:rowData.getColumnValue("FieldType") == "Text Box"; }]]></xp:this.rendered> 
     </xp:inputText> 
    </xp:panel> 
</xp:repeat> 

因此,对于重复的每个成员,变量fieldName成为该行的列值。然后在输入组件的value属性中,使用数组语法(而不是通常的点语法),因为我们想使用变量来指定字段名称,而不是对名称进行硬编码。

在理论上,但是,你应该能够完全跳过数据上下文,只是设置以下是该字段的值表达式:

#{poDoc[rowData.FieldName]}

在默认的情况下( “prefixless”)EL解析器,rowData.FieldName应该精确地返回相同的值,该值rowData.getColumnValue("FieldName")返回在SSJS表达的上下文中。

最后,我建议你阅读this Expression Language tutorial成为熟悉所有的,你可以在核心EL做而不诉诸SSJS的事情。

+2

+1:#{poDoc [rowData.FieldName]}会工作。不幸的是EL通常被开发者低估或误解。 – 2013-04-23 15:00:08

+0

奇怪的是,无论是在第一次担任。我一直在关注一个关于bean为空的错误(使用fieldname作为属性)。然后,我把它与通过复制和粘贴代码,而不是编辑矿井建立dataContexts工作。蒂姆,这是一个拯救生命的人。谢谢! – 2013-04-23 16:42:21