【问题标题】:Wicket component won't refresh via AJAXWicket 组件不会通过 AJAX 刷新
【发布时间】:2016-03-19 19:10:06
【问题描述】:

我有一个 Wicket 页面,其中包含一些应该通过 AJAX 更新的组件。我有以下 AjaxBehavior:

private class MyAjaxBehavior extends AbstractDefaultAjaxBehavior {

        @Override
        public void renderHead(IHeaderResponse response) {
            super.renderHead(response);
            response.renderOnLoadJavascript("wicketAjaxPost(\"" + getCallbackUrl() + "\")");
        }

        @Override
        public void onConfigure(Component component) {
            firstComponent.setOutputMarkupId(true);
            secondComponent.setOutputMarkupId(true);
        }

        @Override
        protected void respond(AjaxRequestTarget target) {
            firstComponent.replaceWith(createFirstComponent());
            target.addComponent(firstComponent);

            secondComponent.replaceWith(createSecondComponent());
            target.addComponent(secondComponent);
        }
    }

我有一个这样的组件层次结构:

Page
- fragment1
  - fragment1-1
    - firstComponent
- secondComponent

问题是firstComponent 在 AJAX 回调后从未刷新。 secondComponent 已正确更新。我试图将firstComponent 移动到frament1-1(只是实验),它成功了!我尝试使用一些额外的片段来包装firstComponent,但它没有帮助。

我尝试调试 Wicket 的 AjaxRequestTarget.respondComponent()。有如下代码:

        // Initialize temporary variables
        final Page page = component.findParent(Page.class);
        if (page == null)
        {
            // dont throw an exception but just ignore this component, somehow
            // it got
            // removed from the page.
            // throw new IllegalStateException(
            // "Ajax request attempted on a component that is not associated
            // with a Page");
            LOG.debug("component: " + component + " with markupid: " + markupId +
                " not rendered because it was already removed from page");
            return;
        }

page 在这里对于 firstComponentsecondComponent 都为空,但第二个以某种方式被重新渲染。

知道为什么不重新渲染firstComponent 吗?我应该在哪里挖?我使用 Wicket 1.4.22。

UPD

我尝试将新组件添加到 target 而不是旧组件。它会在页面上创建新组件,但不会刷新旧组件。所以我在页面上有两个组件而不是一个。由于某种原因,它还破坏了 HTML 标记结构。像这样:

<div>
    <div id="generated">new component is added here</div>
    <table>
        ...
        <tr>old component</tr>
    </table>
</div>

firstComponent 的检票口标记如下所示:

<div>
    <table class="summary" style="width: 100%">
        <tr>
            <div wicket:id="firstComponent" />
        </tr>
    </table>
</div>

...

<wicket:fragment wicket:id="firstComponentFragment">
    <th>title</th>
    <td><span wicket:id="someText"></span></td>
</wicket:fragment>

所以你可以看到新组件被添加到表格之外了。

【问题讨论】:

  • 你应该使用 AjaxEventBehavior("domready"),当 dom 准备好时,它会自动触发你的事件。
  • 所以最后我通过 Javascript 解决了这个问题。 :(

标签: java ajax wicket


【解决方案1】:

有时将父组件(例如表单本身)添加到 ajax 响应目标更容易,这样您就可以确定它下面的所有内容都已更新。因此没有重复或丢失的更新。仅当您需要这种情况下的性能时,才需要仅更新特殊组件。即使您可以定义一个包装容器,您更新它只是为了确保旧标记被删除。

【讨论】:

    【解决方案2】:

    您必须更新新创建的组件:

    @Override
    protected void respond(AjaxRequestTarget target) {
        Component old = firstComponent;
        firstComponent = createFirstComponent();
        old.replaceWith(firstComponent);
        target.addComponent(firstComponent);
    }
    

    更新:&lt;table&gt; 标记内不能有 &lt;div&gt;,否则浏览器会将更新标记附加到表格之外。

    【讨论】:

    • 所以与我的代码的唯一区别是新组件添加到target(不是旧组件)。我试图这样做,但它只是在页面上添加了新组件,而不是刷新旧组件。而且它还在我的 HTML 标记中的错误位置添加了新组件。我更新了答案,请看一下。顺便说一句,我用我的secondComponent 将旧组件添加到target 并正确刷新。
    • 我相信您更新了答案。好吧,我实际上并没有在table 中使用div,这只是定义检票口片段的方式。它应该呈现为&lt;tr&gt;...&lt;/tr&gt;,这是当我第一次使用createFirstComponent() 时,我将此组件添加到页面(正在加载页面时)。似乎是某种 Wicket 错误。
    • 看来您使用的是 Wicket 1.4.x。官方支持的版本是 6.x 和 7.x。该错误可能已在此期间修复。建议您升级!
    • @martin-g 不幸的是我必须使用旧版本。无论如何,我已经通过$('#firstComponent').replaceWith('...') 使用 Javascript(和 JQuery)实现了我的功能。这很尴尬,但它有效。
    猜你喜欢
    • 2016-09-20
    • 2011-05-20
    • 2012-08-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    相关资源
    最近更新 更多