Wicket - 追加Javascript(最佳实践是什么?)

3

我有两个Wicket面板。

ParentPanelChildPanel

场景

ChildPanelParentPanel的一个组件。 每当父面板中发生某个事件时,我想在ChildPanel中添加一些特定的JavaScript代码。

有效解决方案

ParentPanel.java

public class ParentPanel extends Panel
{
    private static final long serialVersionUID = 4306746527837380863L;
    private final ChildPanel childPanel;

    public ParentPanel(String aId, IModel<AnnotatorState> aModel)
    {
        super(aId);
        model = aModel;

        // initially the Child panel is empty. passing empty model
        childPanel = new ChildPanel("child-container", Model.of());
        childPanel.setOutputMarkupId(true);
        add(childPanel);
    }

    @OnEvent
    public void onClickText(RenderEvent aEvent)
    {
        LOG.trace("Event Fired");
        IPartialPageRequestHandler iPartialPageRequestHandler = aEvent.getRequestHandler();

        Integer someData = getSomeData();
        childPanel.setDefaultModel(Model.of(someData));

        //I am trying to add the child panel to the ajax target to ensure rerendering of child panel.
        iPartialPageRequestHandler.add(childPanel);
    }
}

ChildPanel.java

public class ChildPanel extends Panel
{
    private static final long serialVersionUID = -3849226240909011148L;
    private static final Logger LOG = LoggerFactory.getLogger(ChildPanel.class);
    private IModel<Integer> model;

    public ChildPanel(String aId, IModel<Integer> aModel)
    {
        super(aId);
        model = (aModel);
    }

    @Override
    public void renderHead(IHeaderResponse aResponse)
    {
        super.renderHead(aResponse);
        model = (IModel<Integer>) getDefaultModel();

        if (model == null)
            return;
        Integer someData = model.getObject();
        String someJavascript = createSomeJavascript(someData);

        log.debug("Rendering Updated UI with the JS: ", javascript);
        aResponse.render(OnDomReadyHeaderItem.forScript(javascript));
    }
}

显然,每次将childPanel添加到iPartialPageRequestHandler时都会调用renderHead()方法,并更新UI以响应ParentPanel中的每个事件。

问题

然而,有人告诉我这不是一个好习惯。因为在这种情况下,JS被添加到renderHead()中,它最终会出现在页面源代码中-当发送(大量)JSON数据时,这变得很繁琐。需要找到一个好的位置来将JS附加到AJAX目标上(也许是render(),或者更好的是onRender()或onAfterRender()),只要在Wicket中可能/可行。由于我的知识有限,我无法猜测如何实现场景。欢迎和赞赏任何其他(更好或可能)的解决方案。

谢谢。


2
你目前正在做的是在每次渲染时添加一个HeaderItem(即放置在<head>中的片段)。如果你想要做的是在添加组件之前/之后执行某个特定的JS代码,那么你应该查看IPartialPageRequestHandler.prependJavaScriptIPartialPageRequestHandler.appendJavaScript方法。 - Jeroen Steenbeeke
我已经探索了这些方法。但是只有在我有一个ajax目标对象的情况下才能使用它们。这让我产生了疑问,在哪个函数中应该预置javascript,以便每次将子面板添加到请求处理程序时都会调用它。我尝试实现onRender或onAfterRender方法,但我无法获得可以用于调用prependJavaScript方法的ajaxTarget或iPartialPageRequestHandler。 - Sibgha
1
我很确定我从未提到过AjaxRequestTarget。我指的是这些方法: https://ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/core/request/handler/IPartialPageRequestHandler.html#prependJavaScript-java.lang.CharSequence- 和https://ci.apache.org/projects/wicket/apidocs/8.x/org/apache/wicket/core/request/handler/IPartialPageRequestHandler.html#appendJavaScript-java.lang.CharSequence-。 - Jeroen Steenbeeke
1
是的,这些方法存在,但我能否在onRender()中访问IPartialPageRequestHandler对象,以便我可以在该函数中调用prependJavascript? - Sibgha
如果我这样做,刷新页面将会移除JavaScript。我寻找一个像onRender()这样的函数的原因是要确保在按钮点击后刷新页面时也执行它。你可以说一旦按钮被点击并且JS(例如JavaScript图表)出现在ChildPanel UI中,我希望它能够持久化,即使在页面刷新之后,直到下次按钮被点击。在下一个按钮上,我再次想根据点击更新Javascript并更改UI。再次刷新UI(JavaScript)必须持久化。 - Sibgha
显示剩余4条评论
1个回答

1
我猜问题在于createSomeJavascript创建了一大段代码?
那么我会重构它,让createSomeJavascript只调用一个你使用JavaScriptResourceReference添加到组件中的函数。这样,只有一小部分JavaScript代码出现在源代码中。
例如,像这样将你的JavaScript代码放在外部文件中:
private static final ResourceReference  JS_QM   = new JavaScriptResourceReference( ClientPanel.class, "question.mark.js" );


@Override
public void renderHead( Component component, IHeaderResponse response )
{
    super.renderHead( component, response );
    response.render( JavaScriptReferenceHeaderItem.forReference( JS_QM, "question-mark" ) );
    ...
}

如何使用“JavaScriptResourceReference”将JavaScript函数添加到组件中? - Sibgha
如果我按照你建议的方式重构我的函数,那么在函数调用时仍然会传递大量数据块。这是一个图表渲染函数,它需要数据数组以显示学习曲线。你不觉得问题还是一样吗? - Sibgha
啊(你可以通过这些信息改进你的问题 :)。如果这是你的问题,你可以使用一个能够动态获取数据的图表库(例如通过ajax),并使用一个带有回调URL的“行为”,该回调URL将为您获取数据。只需传递回调URL,让JS自己获取数据即可。 - Rob Audenaerde
也许可以查看此链接以获取灵感:https://github.com/adessoAG/wicked-charts - Rob Audenaerde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接