1

我的一个好主意看起来比我最初想象的要少一些。

背景 - 我需要在其中一列中使用 DBLookups 对视图执行经典的重复控制解决方案。我需要对列进行总计,因此我决定使用 viewScope 变量来保存小计,并在计算重复控件的行时添加这些值。

理论上听起来不错,但由于某种原因,如果我在重复控件中使用计算字段,则该值被计算(并附加到小计)两次。我已经通过以下几行代码建立了这一点,在重复中使用了计算字段和编辑框,其中包含相同的代码:

<xp:text escape="true" id="computedField9">
    <xp:this.value><![CDATA[#{javascript:
        //some calculations, nothing to see here*
        var subTotal = viewScope.get("valueColumnTotal");
        viewScope.put("valueColumnTotal", subTotal + sumVals);
        sessionScope.put("Testing", sessionScope.get("Testing") + "~" + sumVals);
        return sumVals;
    }]]></xp:this.value>
    //converters and stuff, nothing to see here
</xp:text>

<xp:inputText id="inputText1">
    <xp:this.value><![CDATA[#{javascript:
        //Same as the computed field above
    </xp:this.value>
</xp:inputText>

对于 1,2 和 3 的值,我的 sessionScope 变量显示 0~1~1~1~2~2~2~3~3~3,小计显示为 18 如果我删除文本框,我得到 0~ 1~1~2~2~3~3 小计 12

换句话说,我得到了计算字段的双值和编辑框的单值。我在那里也得到了一个零,我无法解释,但我假设这只是一个初始值,不需要担心。

我认为这可能是重复被某些东西刷新的情况,但我预计会有 1~2~3~1~2~3。

我猜我只是不了解何时计算计算字段的基本知识,但我很难过。我想我可以切换到编辑框,但我认为计算字段在这里更合适。

有人可以对此有所了解吗?

4

2 回答 2

1

JSF 生命周期揭示了您面临的挑战。正如 Per 指出的那样,您使用的公式分多个阶段执行。确保它们只计算一次的最简单方法是使用以下代码:

        if (view.isRenderingPhase() {
           var subTotal = viewScope.get("valueColumnTotal");
           viewScope.put("valueColumnTotal", subTotal + sumVals);
           sessionScope.put("Testing", sessionScope.get("Testing") + "~" + sumVals);
           return sumVals;
        }

您只需要确保在适当的时间重置该值(例如beforeRenderResponse

另一个独立于循环的选项(即使您不呈现页面,您也可能想要计算一个值)是使用一个小型 Java 类:

       public class SumItUp {

           private HashMap<String, Integer> totals = new HashMap<String,Integer>();        

           public void add(String key, int value) {
               Integer i = new Integer(value);
               this.totals.put(key,i);
           }

           public int getTotal() {
               int result = 0;
               for (Map.Entry<String, Integer> me : this.totals.entrySet()) {
                   result += me.getValue().toInt(); // <-- check that one - off my memory
           }               
       }

将其用作数据上下文或在您的 SSJS 中对其进行初始化。无论多久调用一次计算。当您提交到 Hashmap 时,不会有重复的值。使用 clientid(不是 id,对于重复中的所有控件都相同)或文档的 UNID 作为键 - 它们是唯一的

于 2013-07-17T04:22:47.460 回答
0

如果我正确阅读了要求,则要求是显示列的总数。如果视图有分类列,这是我使用的解决方案,基于Notes In 9 – 019 – Xpages: Getting Column Totals From a View

使用数据上下文从视图中拉入列总计:{** 如果键值没有类别,则此代码行if (entry==null) {return false}else{return entry}返回零}

数据上下文返回列总计或零/假

用于在重复控件中使用一行显示值的表格中的总计显示是使用 xp:facet 完成的,下面的代码作为总计行:

以货币格式显示的类别总数

整个方面看起来像:{** Column #4, 5th column over,在视图中是显示类别总数的列} 在此处输入图像描述

Cut-N-Paste below {**仅供专业的 Cut-n-Paste'ers 使用}

<xp:dataContext var="contractCategory">
    <xp:this.value>
        <![CDATA[#{javascript:
            try{
                var nav:NotesViewNavigator = contractView.createViewNav();
                var query = new java.util.Vector();
                query.addElement(sGrantId);
                var entry:NotesViewEntry = contractView.getEntryByKey(query);
                var entry = nav.getPrev(entry);
                if (entry==null) {return false}else{return entry}
                }catch(e){
                return false;
                }
            }]]>
    </xp:this.value>
</xp:dataContext>



<xp:this.facets>
  <xp:panel xp:key="footer" id="TotalDisplayArea">
    <xp:tr style="background-color:#c9c9c9">
      <xp:this.rendered>
        <![CDATA[#{javascript:getComponent("repeat1").getRowCount();}]]>
      </xp:this.rendered>
      <xp:td colspan="2" styleClass="budget_grid_body lotusBold" style="text-align:left">
      Totals:</xp:td>
      <xp:td styleClass="budget_grid_body" style="text-align:right">&#160;</xp:td>
      <xp:td styleClass="budget_grid_body" style="text-align:center;">
        <xp:div style="text-align:left;float:left;padding-left:20px;">
          <xp:span>$</xp:span>
        </xp:div>
        <xp:div style="float:right;padding-right:5px;">
          <xp:text escape="true" id="totalCostDisp">
            <xp:this.converter>
              <xp:convertNumber pattern="#,##0.00"></xp:convertNumber>
            </xp:this.converter>
            <xp:this.value>
              <![CDATA[#{javascript:
                          (operatingCategory)?
                          operatingCategory.getColumnValues()[4]:
                          "CodeError:4:2"}]]>
            </xp:this.value>
          </xp:text>
        </xp:div>
      </xp:td>
      <xp:td style="background-color:#ffffff"></xp:td>
    </xp:tr>
  </xp:panel>
</xp:this.facets>
于 2014-04-30T23:59:42.963 回答