Wicket:component.onBeforeRender与behavior.onBeforeRender

Wicket:component.onBeforeRender与behavior.onBeforeRender,wicket,Wicket,最近,我需要根据各个子组件的可见性来确定组件的可见性(如果至少有一个子组件可见,则容器应该可见)。 由于我正在各自的onConfigure()方法中设置每个组件的可见性,我无法使用此方法来满足我的需要。所以我切换到onBeforeRender方法,并在那里完成了工作->效果很好。 在那之后,我想将其提取到一个行为中,因为它更易于重用。但我仍然不能使用onconfigure方法,我尝试了相应的beforeRender方法。但是现在wicket抛出了一个异常 “渲染阶段开始后无法修改组件层次结构(页

最近,我需要根据各个子组件的可见性来确定组件的可见性(如果至少有一个子组件可见,则容器应该可见)。 由于我正在各自的onConfigure()方法中设置每个组件的可见性,我无法使用此方法来满足我的需要。所以我切换到onBeforeRender方法,并在那里完成了工作->效果很好。 在那之后,我想将其提取到一个行为中,因为它更易于重用。但我仍然不能使用onconfigure方法,我尝试了相应的beforeRender方法。但是现在wicket抛出了一个异常

“渲染阶段开始后无法修改组件层次结构(页面版本) 那就改变吧!”

我认为这个方法的命名或行为都很奇怪。是否不可能通过行为解决此问题(


你认为呢?

我可能会重写容器的
isVisible()
方法来调用其所有子级的
isVisible()
方法(或者至少直到其中一个返回true为止)


通常我更喜欢重写
isVisible()
,除非可见性取决于外部因素(即组件的模型或子组件以外的任何因素)。这样可读性更强。显然,如果这样做,您必须注意的是永远不要在
isVisible()中调用昂贵的操作
实现。

我可能会重写容器的
isVisible()
方法来调用其所有子级的
isVisible()
方法(或者至少在其中一个返回true之前)


通常我更喜欢重写
isVisible()
,除非可见性取决于外部因素(即组件的模型或子组件以外的任何因素)。这样可读性更强。显然,如果这样做,您必须注意的是永远不要在
isVisible()中调用昂贵的操作
实现。

看一看
EnclosureContainer
,它完全实现了您的要求,但只针对一个孩子。它应该很容易扩展到多个孩子

诀窍是在容器的
isVisible()
中调用子类的
onConfigure
方法:

组件#onconfig()

*例如链接到 *两个标记容器应执行以下操作: * * *最终WebMarkupContainer源=新的WebMarkupContainer(“a”){ *配置()上受保护的空{ *setVisible(Math.rand()>0.5f); * } * }; * *WebMarkupContainer linked=新的WebMarkupContainer(“b”){ *配置()上受保护的空{ *source.configure();//确保已配置源 *setVisible(source.isVisible()); * } *}


这是基于Wicket 1.5的

来看看
EnclosureContainer
,它完全实现了您的要求,但只针对一个孩子。它应该很容易扩展到多个孩子

诀窍是在容器的
isVisible()
中调用子类的
onConfigure
方法:

组件#onconfig()

*例如链接到 *两个标记容器应执行以下操作: * * *最终WebMarkupContainer源=新的WebMarkupContainer(“a”){ *配置()上受保护的空{ *setVisible(Math.rand()>0.5f); * } * }; * *WebMarkupContainer linked=新的WebMarkupContainer(“b”){ *配置()上受保护的空{ *source.configure();//确保已配置源 *setVisible(source.isVisible()); * } *}


这是基于Wicket 1.5的可能是一个解决方案。但是,我还是更愿意在行为中实现逻辑,因为这更易于重用。我不知道,创建一个抽象的
OnlyVisibleIfChildIsVisibleContainer
组件对我来说听起来是非常可重用的。问题是,在这种情况下,我绑定到这个容器。我不能将相应的行为附加到列表中视图、边框或任何其他组件。逻辑将“绑定”在层次结构中,并位于该容器内。您不能将行为附加到ListView,但可以将ListView放在自定义容器中(例如ShyContainer)。可以为此类容器提供对某些组件的引用以检查可见性。在onBeforeRender()调用期间,行为无法操纵组件的可见性设置。这是因为组件已确定它将可见(并且无论对visible标志执行什么操作,都将继续执行其渲染例程)因此,如果要使用某个行为执行此操作,则应:-重写Behavior.onConfigure()方法-检查是否为MarkupContainer(?),迭代子项,对其调用“configure()”,并检查其是否可见。重写isVisible()可能是一个解决方案。但是,我还是更愿意在行为中实现逻辑,因为这更易于重用。我不知道,创建一个抽象的
OnlyVisibleIfChildIsVisibleContainer
组件对我来说听起来是非常可重用的。问题是,在这种情况下,我绑定到这个容器。我不能将相应的行为附加到列表中视图、边框或任何其他组件。逻辑将“绑定”在层次结构中,并位于该容器内。您不能将行为附加到ListView,但可以将ListView放在自定义容器中(例如ShyContainer)。可以为此类容器提供对某些组件的引用以检查可见性。在onBeforeRender()调用期间,行为无法操纵组件的可见性设置。这是因为组件已确定它将可见(并将继续它的渲染例程,无论您对可见标志做了什么)因此如果
public boolean isVisible()
{
    child.configure();
    return child.determineVisibility();
}
* EG to link visiliby of * two markup containers the following should be done: * * * final WebMarkupContainer source=new WebMarkupContainer("a") { * protected void onConfigure() { * setVisible(Math.rand()>0.5f); * } * }; * * WebMarkupContainer linked=new WebMarkupContainer("b") { * protected void onConfigure() { * source.configure(); // make sure source is configured * setVisible(source.isVisible()); * } * }