Java Tapestry:为什么onActivate方法被调用两次?

时间:2015-07-28 14:51:43

标签: java tapestry

我有一个挂毯页面,其中有两个带有不同参数的onActivate()方法。

//在这种情况下调用两种方法

void onActivate(String filterSetJson) {
    schema = getSchema();
    if (ValueHelper.isDefined(filterSetJson) && !filterSetJson.equals("all")) {
        setFilterSet( filterSetJson );
    }
    else {
        setFilterSet("{}"); // Empty filter set
    }
    this.loadedTagSummary = false;
    sortOrderForTags="count";
    sortOrderForTypes="count";
}


void onActivate(String filterSetJson, int pageCount) {
    //onActivate( filterSetJson );
    this.pageCount = pageCount;
}

有时这个页面是用两个参数调用的,有时是一个。问题是当使用两个参数调用页面时,都会调用onActivate()方法。只应调用接受两个参数的方法。

正如下面的链接所示,我修改了代码只有一个onActivate()方法,它接受EventContext作为参数。 http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Multiple-onActivate-methods-td2434897.html#a2434901

所以修改后的代码如下。

//在这种情况下调用以下方法两次

Object onActivate(EventContext eContext){
    int paramCount = eContext.getCount();
    if( paramCount == 0 )   return true;
    String filterSetJson = eContext.get(String.class, 0);
    if( paramCount > 1 ){
        int pageCount = eContext.get(Integer.class, 1);
        this.pageCount = pageCount;
    }
    schema = getSchema();
    if (ValueHelper.isDefined(filterSetJson) && !filterSetJson.equals("all")) {
        setFilterSet( filterSetJson );
    }
    else {
        setFilterSet("{}"); // Empty filter set
    }
    this.loadedTagSummary = false;
    sortOrderForTags="count";
    sortOrderForTypes="count";
    return true;    
}

现在,问题是onActivate()仍然被调用两次。一旦参数出现,另一次没有参数(我认为这次EventContext是空的)。因此,我必须添加对参数的检查,如果它们不存在则返回。这样可以避免整个代码执行两次,但仍然不是一个干净的修复程序。我不明白为什么这个方法被调用两次。我考虑了一些邮件列表帖子中提出的潜在原因。

1:我确信页面上没有图像被赋予相对路径。所有图像都加载了“上下文”

2:没有超类实现onActivate()方法。它只出现在这个课程中。

有趣的是,如下面的链接所示,如果我从onActivate()方法返回true,那么只调用一个方法并修复问题! http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/T5-onActivate-called-twice-td2428923.html

这是可以正常使用的代码。

//在这种情况下只调用一个方法。这是正确的行为

Object onActivate(String filterSetJson) {
    schema = getSchema();
    if (ValueHelper.isDefined(filterSetJson) && !filterSetJson.equals("all")) {
        setFilterSet( filterSetJson );
    }
    else {
        setFilterSet("{}"); // Empty filter set
    }
    this.loadedTagSummary = false;
    sortOrderForTags="count";
    sortOrderForTypes="count";
    return true;
}


Object onActivate(String filterSetJson, int pageCount) {
    //onActivate( filterSetJson );
    this.pageCount = pageCount;
    return true;
}

我可以忍受这个解决方案,但我不明白这里发生了什么。任何人都可以了解为什么onActivate()方法在它们不返回true时被调用或为什么onActivate(EventContext eContext)被调用两次?

发布这个问题的另一个原因是为自己和其他人记录这个问题,因为我在这个问题上花了很多时间。

Tapestry版本为5.3

1 个答案:

答案 0 :(得分:1)

请阅读here页面,特别是

  

一个好的“经验法则”是使用onActivate(...)和onPassivate()只是接收和返回激活上下文。

您应该小心使用onActivate,因为有时可能会调用它(例如,在呈现pagelink时)。您的onActivate方法应该是“哑”,只需存储值,仅此而已。把你的逻辑放在另一个事件中(例如setupRender)。

我似乎还记得tapestry中的一些奇怪的逻辑,它会调用所有onActivate()方法,其值等于或小于URL上的页面激活上下文变量的数量。

我要么:

1)使用单个onActivate(EventContext)方法存储值。将任何逻辑移至setupRender

2)使用@PageActivationContextsetupRender

@PageActivationContext(index=0)
private String filterSetJson;

@PageActivationContext(index=1)
private Integer pageCount;

void setupRender() {
    if (pageCount == null) {
        ...
    } else {
        ...
    }
}

注意:多个@PageActivationContext是最近new feature

这两个选项大致相当。