重复控件中的动态绑定

Dav*_*rre 4 xpages

在采购订单模块中,我们需要根据来源选择方法,竞争类型和PO的总成本询问某些问题.这些问题可能会随着时间的推移而在数据库的不同实例之间发生变化.

所以我有一个包含问题的视图,这样我就可以动态地向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>
Run Code Online (Sandbox Code Playgroud)

我已经尝试了各种方法来做到这一点,包括使一个dynamicInputText自定义控件传入字段名称,但没有运气.我得到的最接近的是我用这个:

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

这给了我类似#{poDoc.justification}的东西,这是我想要传递给'绑定'的东西,但它最终显示为文本值.

我确实尝试使用$来计算加载时的值,但我猜它不起作用,因为我的(和rowData)视图在加载时不可用.当我想要使用部分刷新时,由于更新了我想要显示哪些字段的标准,这最终会出现问题.

其他问题的一些答案看起来很有希望,但没有提供代码,所以我无法弄明白.

Tim*_*ony 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>
Run Code Online (Sandbox Code Playgroud)

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

但是,理论上,您应该能够完全跳过数据上下文,只需将以下内容设置为该字段的值表达式:

#{poDoc[rowData.FieldName]}

在缺省("prefixless")EL解析器的上下文中,rowData.FieldName应精确地返回相同的值rowData.getColumnValue("FieldName")在一个SSJS表达的上下文中返回.

最后,我建议您阅读这个表达式语言教程,以熟悉您可以在核心EL中执行的所有操作,而无需借助SSJS.

  • +1:#{poDoc [rowData.FieldName]}可以正常工作.不幸的是EL通常被开发人员低估或误解. (2认同)