我遇到过在部分更新设置的字段上使用onChange事件时,部署更新的执行是在之前执行实际事件的SSJS代码。
有没有办法扭转这种局面?
在我附上的例子中,我有三个字段,一个隐藏输入和一个计算值。
用户在这三个字段中输入值,隐藏组件有一个公式来计算上面字段的总和。标称*价格+费用= PaymentAmount。
现在,客户希望在PaymentAmount之前获得预先计算的费用值;在我的例子中,我使用0.15%的硬编码值
公式将是PaymentAmount =(标称*价格*费用)+(标称*价格)
我们已将PaymentAmount设置在一个表中,我们已将该行标记为 PaymentAmountRow ,以便能够更新其中的两个组件。
所有组件都用于对 PaymentAmountRow 进行部分更新,但现在我还需要组件价格来更新Fee1。我想如果我将部分更新更改为高于一切的组件,在这种情况下,周围的面板名为 dealInfo 它将正常工作但令我惊讶的是,在实际代码之前触发了部分组件的计算计算费用。
我已尝试过该事件的所有可用参数,但它们都没有工作......
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core">
<xp:this.resources>
<xp:script
src="/CommonSSJS.jss"
clientSide="false"
>
</xp:script>
</xp:this.resources>
<xp:panel id="dealInfo">
<xp:this.data>
<xp:dominoDocument
var="document1"
formName="EquityTrade"
>
</xp:dominoDocument>
</xp:this.data>
<xp:label
value="Nominal"
id="label2"
>
</xp:label>
<xp:inputText
id="Nominal"
value="#{document1.Nominal}"
>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="PaymentAmountRow"
>
<xp:this.action><![CDATA[#{javascript:print("Nominal onChange - partial PaymentAmount");}]]></xp:this.action>
</xp:eventHandler>
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
</xp:inputText>
<xp:br></xp:br>
<xp:label
value="Price"
id="label1"
>
</xp:label>
<xp:inputText
id="Price"
value="#{document1.Price}"
>
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="Fee1">
<xp:this.action><![CDATA[#{javascript:print("Price onChange - update")
var Fee1:com.ibm.xsp.component.xp.XspInputText = getComponent("Fee1");
var feeDef = 0.15;
var Nominal:com.ibm.xsp.component.xp.XspInputText = getComponent("Nominal");
var Price:com.ibm.xsp.component.xp.XspInputText = getComponent("Price");
var fee = Nominal.getValue()*Price.getValue()*feeDef
Fee1.setValue(fee);
}]]></xp:this.action>
</xp:eventHandler>
</xp:inputText>
<xp:br></xp:br>
<xp:label
value="Fee 1"
id="label3"
>
</xp:label>
<xp:inputText
id="Fee1"
value="#{document1.Fee1}"
>
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
<xp:this.valueChangeListener><![CDATA[#{javascript:print("Value changed");
}]]></xp:this.valueChangeListener>
<xp:eventHandler
event="onchange"
submit="true"
refreshMode="partial"
refreshId="PaymentAmountRow"
></xp:eventHandler>
</xp:inputText>
<xp:br></xp:br>
<xp:table>
<xp:tr id="PaymentAmountRow">
<xp:td>
<xp:inputHidden
id="PaymentAmount"
value="#{document1.PaymentAmount}"
>
<xp:this.converter>
<xp:customConverter getAsString="#{javascript:return value.toString();}">
<xp:this.getAsObject><![CDATA[#{javascript:try {
print("PaymentAmount calculation");
var Nominal:com.ibm.xsp.component.xp.XspInputText = getComponent("Nominal");
var Price:com.ibm.xsp.component.xp.XspInputText = getComponent("Price");
var Fee1:com.ibm.xsp.component.xp.XspInputText = getComponent("Fee1");
var nominal = Nominal.getValue();
var price = Price.getValue();
var fee1= Fee1.getValue();
var paymentAmount = nominal * price;
paymentAmount+=fee1;
return paymentAmount;
} catch(e){
dBar.info(e);
}}]]></xp:this.getAsObject>
</xp:customConverter>
</xp:this.converter>
</xp:inputHidden>
<xp:text
escape="true"
id="computedField14"
>
<xp:this.value><![CDATA[#{document1.PaymentAmount}]]></xp:this.value>
<xp:this.converter>
<xp:convertNumber type="number"></xp:convertNumber>
</xp:this.converter>
</xp:text>
</xp:td>
</xp:tr></xp:table>
</xp:panel>
</xp:view>
答案 0 :(得分:1)
我不是100%确定我理解代码或导致问题的部分,但我认为转换器的getAsObject()在应用程序逻辑之前运行eventHandler并没有得到正确的值。所以这里:
XPages(和JSF)部分刷新生命周期分为六个阶段: 1)还原视图重建组件树,以便我们可以将发送的HTML映射回底层Java对象。 2)应用请求值获取在HTML中输入的字符串值,并将它们放在每个相关组件的submittedValue属性中。 3)流程验证运行所有转换器和验证器,以确保submittedValue属性可以转换为基础数据类型,并传递服务器上定义的任何验证规则。 4)更新模型值获取那些submittedValues(现在我们知道我们可以将它们应用到数据模型而不会搞砸!),将字符串转换为相关的数据类型,将它们放在value属性中并设置submittedValue为null。 (它可能在进程验证阶段转换了字符串并将它们存储在内部变量中,因此它只需要在此阶段更新value和submittedValue,不确定。) 5)调用应用程序运行您的eventHandler逻辑。 6)渲染响应为浏览器生成更新的HTML。
您无法更改订单。因此,必须在更新模型值之前运行流程验证。否则,更新模型值可能会因为数据类型错误而中断,或者您存储了无效值,然后将其写入基础文档。
我认为问题是你转换器正在使用getComponent()。getValue()。但是在过程验证阶段(即转换器的getAsObject()方法正在运行时)已经设置了值。
如果是这样,您实际需要的是:
或
如果使用后者,则应该能够避免使用inputHidden。