简体   繁体   English

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

[英]Java Tapestry : why is onActivate method called twice?

I have a tapestry page in which I have two onActivate() methods with different parameters. 我有一个挂毯页面,其中有两个具有不同参数的onActivate()方法。

// both the methods are called in this case //在这种情况下,两个方法都被调用

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;
}

Sometimes this pages is invoked with two arguments, sometimes with one. 有时,此页面使用两个参数调用,有时使用一个。 The problem is that when the page is invoked with two parameters, both onActivate() methods are called. 问题在于,当使用两个参数调用页面时,两个onActivate()方法都会被调用。 Only the method which accepts two parameters should be called. 仅应调用接受两个参数的方法。

As suggested in link below, I modified code to have just one onActivate() method which accepts EventContext as a parameter. 如下面的链接中所建议,我修改了代码,使其仅具有一个将EventContext作为参数的onActivate()方法。 http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Multiple-onActivate-methods-td2434897.html#a2434901 http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/Multiple-onActivate-methods-td2434897.html#a2434901

So the modified code is as follows. 因此,修改后的代码如下。

// the following method is called twice in this case //在这种情况下,以下方法被调用了两次

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;    
}

Now, the problem is that onActivate() is still called twice. 现在,问题在于onActivate()仍被调用两次。 Once the parameters are present and the other time there are no parameters(I think the EventContext is empty this time). 一旦存在参数,其他时候就没有参数(我认为这次EventContext为空)。 Therefore I had to add the check for parameters and return if they are not present. 因此,我必须添加对参数的检查,如果不存在则返回。 This avoids the whole code being executed twice but is still not a clean fix. 这样可以避免整个代码执行两次,但这仍然不是一个好办法。 I don't understand why the method is called twice. 我不明白为什么该方法被调用两次。 I have considered following potential reasons as suggested in some mailing list posts. 我已经考虑了某些邮件列表帖子中建议的以下潜在原因。

1: I am sure there is no image on page being given a relative path. 1:我确定页面上没有图像被指定相对路径。 All images are loaded with 'context' 所有图像都加载了“上下文”

2: There is no super class implementing onActivate() method. 2:没有实现onActivate()方法的超类。 It is only present in this class. 它仅在此类中存在。

Interestingly as suggested in link below, if I return true from both onActivate() methods, then only one method is called and the problem is fixed! 有趣的是,如下面的链接中所建议,如果我从两个onActivate()方法中都返回true,则仅调用一个方法,并且问题已解决! http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/T5-onActivate-called-twice-td2428923.html http://apache-tapestry-mailing-list-archives.1045711.n5.nabble.com/T5-onActivate-called-twice-td2428923.html

This is the code which works fine. 这是可以正常工作的代码。

// only one method is called in this case. //在这种情况下,仅调用一种方法。 This is the correct behavior 这是正确的行为

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;
}

I can live with this solution but I don't understand what is happening here. 我可以接受这种解决方案,但是我不明白这里发生了什么。 Can anyone throw light on why both onActivate() methods are called when they don't return true or why onActivate(EventContext eContext) is called twice? 谁能阐明为什么两个onActivate()方法在未返回true时都被调用,或者为什么两次调用onActivate(EventContext eContext)的原因?

The other reason for posting this question is to document this for myself and for others since I have spent a lot of time in this issue. 发布此问题的另一个原因是为我自己和其他人记录此问题,因为我在此问题上花费了很多时间。

Tapestry version is 5.3 Tapestry版本是5.3

Please read the page here , in particular 请特别在这里阅读页面

A good "rule of thumb" is to use onActivate(...) and onPassivate() for no more than receiving and returning the activation context. 一个好的“经验法则”是使用onActivate(...)和onPassivate()仅用于接收和返回激活上下文。

You should be careful with onActivate as it can be called at times you may not expect (for instance when rendering a pagelink ). 您应谨慎使用onActivate因为它可能在您不希望的时候被调用(例如,呈现pagelink )。 Your onActivate method should be 'dumb' and simply store the values, nothing more. 您的onActivate方法应该是“哑巴”, onActivate ,仅此而已。 Put your logic in another event (eg setupRender). 将您的逻辑放在另一个事件中(例如setupRender)。

I also seem to remember some strange logic in tapestry where it will call all onActivate() methods with equal to or less than the number of page activation context variables on the URL. 我似乎还记得挂毯中的一些奇怪逻辑,该逻辑将调用等于或小于URL上页面激活上下文变量数量的所有onActivate()方法。

I'd either: 我要么:

1) Have a single onActivate(EventContext) method to store the values. 1)有一个onActivate(EventContext)方法来存储值。 Move any logic to setupRender . 将任何逻辑移动到setupRender

2) Use @PageActivationContext and setupRender 2)使用@PageActivationContextsetupRender

@PageActivationContext(index=0)
private String filterSetJson;

@PageActivationContext(index=1)
private Integer pageCount;

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

Note: Multiple @PageActivationContext is a recently new feature 注意:Multiple @PageActivationContext是最近新增的功能

These two options are roughly equivelant. 这两个选项大致相当。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM