如何在Wicket的setResponsePage()中添加锚点?

4
我们需要将访问特定URL的用户重定向到Wicket页面,并滚动到页面中的锚点。例如,用户直接链接到http://.../target/url/123。之后,从数据库中查找123 id。随后,根据实体是否被找到,将重定向用户到不同的页面。
在获取实体之后,用户应该被重定向到http://.../another/url/123#element123。我们如何使用Wicket实现这一点?页面也应该可以不带锚点访问,并且最好是通用的解决方案。
我想到的一个解决方案是覆盖PageParametersEncoder逻辑,当PageParameters包含名为anchor的条目时,在URL后附加#anchor。然而,这意味着我还需要扩展Url类以附加锚点。
public class ExtendedEncoder extends PageParametersEncoder {

    public static final String ANCHOR = "anchor";

    @Override
    public Url encodePageParameters(PageParameters pageParameters) {
        Url fromSuper = super.encodePageParameters(pageParameters.remove(ANCHOR));
        return new ExtendedUrl(fromSuper,
                pageParameters.get(ANCHOR).toOptionalString());

    }
}

public class ExtendedUrl extends Url {
        private String anchor;

        private ExtendedUrl(Url url, String anchor) {
            super(url);
            this.anchor = anchor;
        }

        @Override
        public String toString(StringMode mode, Charset charset) {
            return super.toString(mode, charset)
                   + anchor == null ? "" : "#" + anchor;
        }
    }
}

有没有其他的解决方案?
2个回答

1
以下代码将把一个JavaScript片段渲染到您的目标页面的HTML中,当页面加载时,它将使页面聚焦于URL中指定的锚点。
@Override
public void renderHead(IHeaderResponse response) {
    super.renderHead(response);
    long anchor = getRequest().getQueryParameters().getParameterValue("anchor").toLong(0);
    if (anchor > 0) {
        response.render(new OnLoadHeaderItem("location.href='#anchor" + anchor + "';"));
        anchor = 0;
    }
}

顺便提一下,这是针对Wicket 6的。但在1.5和之前的版本中也可以做类似的事情。


是的,那样做可以解决问题。然而,它会使anchor参数在URL中可见,像/page/123?anchor=foo#foo这样。此外,你需要在每个页面中添加代码,所以它并不是很通用。 - RJo
@rjokelai 我通常会有一个基础页面,从中派生出应用程序的所有页面,因此这对我来说从未成为问题。我在内容页面中使用此模式,其中锚参数是注释ID,并将其在URL中可见不是问题。但是,如果您正在寻找仅在渲染时解决方案,则您的唯一选择是Wicket6和使用自定义PageParameterEncoder的解决方案,该编码器添加了一个附加的#字符并将您的锚标签移动到参数列表的末尾。我认为在apache.issues.org上开启功能请求票证是一个好主意。 - cserepj
我认为在Wicket 1.5中也可以覆盖PageParametersEncoder,因为它作为参数传递给了MountedMapper。虽然这会使URL变得有点丑陋,但我认为我们会选择JavaScript解决方案 :) - RJo

0
你可以请求页面的URL,然后进行重定向。
String fullUrl = RequestCycle.get().getUrlRenderer()
    .renderFullUrl(Url.parse((String) urlFor(RedirectPage.class,parameters)));
setResponsePage(new RedirectPage(fullUrl+"#anchor"));

不错,但 Wicket 抱怨:无法从类org.apache.wicket.markup.html.pages.RedirectPage创建页面。类没有可见的默认构造函数。 我认为这是因为它试图使用 RedirectPage(PageParameters) 构造函数实例化 RedirectPage,但该构造函数不存在。 - RJo
此外,fullUrl 似乎包含 http://localhost:8080/...。在实际环境中它真的能正常工作吗? - RJo
可能我正在运行不同的Wicket版本,1.5版。 - osdamv
我们也在使用 Wicket 1.5。 - RJo

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