Xpages 在页面级别计算和存储数据以用于自定义控件

Xpages 在页面级别计算和存储数据以用于自定义控件,xpages,Xpages,我必须做一些我的许多控件需要的计算,我只想在每个请求时做一次并存储它。(例如,在渲染响应之前) 我想不出一个干净的方法来在自定义控件中实现这一点 我不想使用dataContext,因为我读了一些关于其性能的令人毛骨悚然的文章(在一个JSF循环中进行多次计算)。 见: 因此,我转到objectData,只是想弄清楚,它与compositeData存在相同的问题-它在任何自定义控件事件中都不可用,但在页面加载之前和页面加载之后可用。 见: 当前解决方案 对于那个问题我有两个(不令人满意的)解决方案

我必须做一些我的许多控件需要的计算,我只想在每个请求时做一次并存储它。(例如,在渲染响应之前)

我想不出一个干净的方法来在自定义控件中实现这一点

我不想使用dataContext,因为我读了一些关于其性能的令人毛骨悚然的文章(在一个JSF循环中进行多次计算)。
见:

因此,我转到objectData,只是想弄清楚,它与compositeData存在相同的问题-它在任何自定义控件事件中都不可用,但在页面加载之前和页面加载之后可用。
见:

当前解决方案

对于那个问题我有两个(不令人满意的)解决方案

我在下面的标记中将解决方案标记为

解决方案#1: 滥用xp:text的属性“value”来更新objectData

解决方案#2: 需要手动调用update()方法

测试设置

XPage


我喜欢做的是


但这似乎不可能,看看sayHello()调用会发生什么

第一个请求

后续请求


我欣赏每一个想法或提示:)

任何自定义控件的一个重要设计原则是封装。如果将其拖到画布(页面,customControl)上,它应该可以工作,而不依赖于现有条件

所以控制使用的参数应该是,井参数。在控件定义中将它们定义为自定义参数

然后有两个选项:使用保存在viewScope中的SsJS对象或在viewScope中使用托管bean

假设您的控件需要一个名为color的参数,那么该控件的调用方式如下:

  <xc:myControl color="#{pageBean.color}"></xc:myControl>
只有当值不相互依赖时,延迟加载才有意义


让我们知道进展如何

你是否考虑使用SeaSistVistar变量来存储数据?我的思想使用请求范围,而不是(如你所提到的,懒惰加载)。这确保了对每个请求进行重新计算,但每个请求只进行一次。但看起来托管bean在所有自定义控件之间共享,我喜欢为每个自定义控件实例化一个托管bean。当我想将requestScope与POJO一起使用时,如何实现实例化?您可以使用Facet模式,并拥有一个bean,如果不同控件需要不同的东西,它可以为您返回不同控件的对象。您可能希望实现映射接口,我理解-我想我可以使用Sven Hasselbach()中的getCCId()来标识当前的自定义控件。非常感谢,你们真是太棒了:)
<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xe="http://www.ibm.com/xsp/coreex" xmlns:xc="http://www.ibm.com/xsp/custom"
    beforePageLoad="#{javascript:object1.sayHello('beforePageLoad')}" 
    afterPageLoad="#{javascript:object1.sayHello('afterPageLoad')}"
    afterRestoreView="#{javascript:object1.sayHello('afterRestoreView')}" 
    beforeRenderResponse="#{javascript:object1.sayHello('beforeRenderResponse')}"
    afterRenderResponse="#{javascript:object1.sayHello('afterRenderResponse')}">
    <xp:this.data>
        <xe:objectData var="object1">
            <xe:this.createObject><![CDATA[#{javascript://
                print("object1 is created");
                return new ds.DataTest();   }]]>
            </xe:this.createObject>
        </xe:objectData>
    </xp:this.data>

    <!-- Solutions -->

    <!-- Solution #1 -->    
    <xp:text id="computedField1" value="#{javascript: object1.update(); return ''; }" />

    <!-- Solution #2  -->
    <xp:button value="dataObject update" id="updateButton">
        <xp:eventHandler event="onclick" submit="true" refreshMode="complete">
            <xp:this.action><![CDATA[#{javascript:object1.update()}]]></xp:this.action>
        </xp:eventHandler>
    </xp:button>

    <!-- /Solutions -->

    <div>
        Object1 current value:
        <xp:text escape="true" id="output" value="#{object1.value}" />
    </div>

    <xp:button value="Update" id="updateButton2">
        <xp:eventHandler event="onclick" submit="true" refreshMode="complete" />
    </xp:button>
</xp:view>
package ds;

import java.io.Serializable;

public class DataTest implements Serializable {
    private static final long serialVersionUID = 1L;
    private String value = "";

    public DataTest() { /* Constructor */ }

    public void sayHello(String text){
        System.out.println("Hello from: " + text);
    }

    public void update() {
        value = Double.toString( Math.random() );
    }

    public void setValue(String value) {
        this.value = value;
    }
    public String getValue() {
        return value;       
    }

}
<xp:view beforeRenderResponse="#{javascript:object1.update()}">
  <xc:myControl color="#{pageBean.color}"></xc:myControl>
    public synchronized String getColor() {
            if(this.color==null) {
                  this.initColor();
            }
            return this.color;
    }