重复控制中的计算字段 - 计算两次(并破坏小计!)

时间:2013-07-17 01:51:25

标签: xpages

我的一个聪明的想法看起来不像我想象的那么明亮。

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

理论上听起来不错,但出于某种原因,如果我在重复控件中使用Computed Field,则计算值(并附加到小计)两次。我已经使用以下代码中的代码建立了这个,使用计算字段和编辑框,在重复内部使用相同的代码:

<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。

我猜我只是不明白计算计算字段的基本原理,但我很难过。我想我可以切换到编辑框,但我认为计算字段在这里更合适。

有人可以对这一点有所了解吗?

2 个答案:

答案 0 :(得分:1)

JSF Lifecycle揭示了你所面临的挑战。您使用的公式按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作为键 - 它们是唯一的

答案 1 :(得分:0)

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

datacontext用于从视图中提取列总数: {**这行代码 if(entry == null){return false} else {return entry} 如果没有键值类别,则返回零}

Datacontext returning column total or zero/false

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

Category total shown formatted for currency

整个方面看起来像: {**第4列,第5列结束,在视图中显示类别总计} enter image description here

切割N-Paste以下{**仅供专业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>