【问题标题】:How to wire up GWT hyperlink click handler?如何连接 GWT 超链接点击处理程序?
【发布时间】:2012-11-07 12:21:56
【问题描述】:

我是 GWT 的新手,我正在努力实现以下目标:

这是我编写的代码:

public class MyWebApp implements EntryPoint {
    // The main container for everything the user sees (the "view")
    private LayoutPanel mainPanel;

    // Simple HTML for the header ("MyWebApp") and subsequent <hr/>
    private SafeHtml header;

    // The three links "Dashboard", "Monitors" and "Help Desk"
    private HorizontalPanel navMenu;

    // The empty content that gets populated when user clicks one of
    // the 3 links.
    private Panel menuContent;

    @Override
    public void onModuleLoad() {
        // The initial fragment contains the header, nav menu and empty "content" div.
        // Each menu/screen then fills out content div.
        initMainPanel();

        RootPanel.get().add(mainPanel);
    }

    private void initMainPanel() {
        SafeHtmlBuilder headerBuilder = new SafeHtmlBuilder();
        navMenu = new HorizontalPanel();

        // Leaving null until user clicks on one of the 3 menus.
        // Then the menu will decide what panel gets injected for
        // this panel.
        menuContent = null;

        // Create the simple HTML for the header.
        headerBuilder.append("<h1>MyWebApp</h1><hr/>");

        // Create the navMenu items.
        Hyperlink dashboardLink, monitorsLink, helpDeskLink;

        // Homepage is http://www.mywebapp.com
        // I want the dashboardLink to inject menuContent and "redirect" user to
        // http://www.mywebapp.com/dashboard
        dashboardLink = new Hyperlink("???", "???");

        // http://www.mywebapp.com/monitors
        monitorsLink = new Hyperlink("???", "???");

        // http://www.mywebapp.com/help-desk
        helpDeskLink = new Hyperlink("???", "???");
        navMenu.add(dashboardLink);
        navMenu.add(monitorsLink);
        navMenu.add(helpDeskLink);

        // Add all widgets to the mainPanel.
        mainPanel.add(new HTML(headerBuilder.toSafeHtml().toString()));
        mainPanel.add(navMenu);
        mainPanel.add(menuContent);

        // Position and size the widgets (omitted for brevity).
        // mainPanel.setWidgetHorizontalPosition(...);
    }

    private HTML getDashboardMenuContent() {
        return new HTML("This is the dashboard.");
    }

    private HTML getMonitorsMenuContent() {
        return new HTML("These are the monitors.");
    }

    private HTML getHelpDeskMenuContent() {
        return new HTML("This is the help desk.");
    }
}

最重要的是:

  • 如何“连接”Hyperlinks,以便当用户单击它们时,我可以调用适当的 getXXXMenuContent() 方法,然后将其添加到 menuContent?

还有:

  • 我感觉好像我在这里做错了什么:mainPanel.add(new HTML(headerBuilder.toSafeHtml().toString())); - 如果是这样,那是什么?!?我应该如何以安全(因此使用 Safe* 对象)、高效且符合推荐做法的方式添加简单的 &lt;h1&gt; 和 &lt;hr/&gt;?
  • 我应该在这里实现UiBinder 吗?如果是这样,我会为每个菜单的内容创建UiBinders,还是为整个mainPanel,或两者兼而有之?

提前致谢!

【问题讨论】:

    标签: java gwt uibinder


    【解决方案1】:

    Hyperlink 小部件触发导航。您不想处理对它们的点击,您想处理导航(可以通过单击 Hyperlink 或使用浏览器的后退/前进按钮、书签或其他地方的链接来触发 - 包括 Ctrl+单击 @987654325 @ 在新窗口/标签中打开它-等)

    要对这些导航事件做出反应,请使用History.addValueChangeHandler;要在应用程序启动时处理初始导航,请调用History.fireCurrentHistoryState()(当然是在添加处理程序之后)。

    更多详情请见:https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsHistory


    最好将其他问题拆分为...其他问题,但无论如何这里是答案:

    我觉得我在这里做错了什么:mainPanel.add(new HTML(headerBuilder.toSafeHtml().toString())); - 如果是这样,那是什么?!?我应该如何以安全(因此使用 Safe* 对象)、高效且符合推荐做法的方式添加简单的 &lt;h1&gt; 和 &lt;hr/&gt;?

    HTML 小部件的构造函数采用 SafeHtml,因此您无需调用 toString()。
    如果您只使用常量,则不需要SafeHtmlBuilder;请改用SafeHtmlUtils。但是无论有没有SafeHtml、SafeHtml,常量都不会或多或少安全,这只会让您更容易在代码中找到所有出现的HTML,以帮助对您的应用进行安全审查(顺便说一句,我们正在做 HTML,所以 &lt;hr&gt;,而不是 &lt;hr/&gt;;如果你真的希望它看起来像 XML/XHTML,那么使用 &lt;hr /&gt; 但你只是 cheating yourself 这里)

    我应该在这里实现UiBinder 吗?如果是这样,我会为每个菜单的内容创建UiBinders,还是为整个mainPanel,或两者兼而有之?

    如果您觉得不需要 UiBinder,则不必使用它。但在这种情况下,它不会改变任何东西:您处理的不是小部件事件,而是历史事件。

    【讨论】:

    • 感谢@Thomas Broyer (+1) - 我实际上对使用活动/地点很感兴趣。所以我想问的正确问题是:如何让超链接触发导航,例如触发新的PlaceChangeRequest?
    • 不要使用Hyperlink 然后,使用Anchor(使用您的PlaceHistoryMapper 生成setHref 值)和调用PlaceController#goTo 的ClickHandler(不要'不要忘记event.preventDefault())。好吧,从技术上讲,您也可以使用Hyperlink,但是如果用户取消导航(如果您的活动从mayStop 返回非空值),那么与PlaceController#goTo 相反,URL 已经改变了。
    【解决方案2】:

    有点像

    dashboardLink.addClickHandler( 
       new ClickHandler() 
       {
           public void onClick( ClickEvent event ) 
           {
               mainPanel.setWidget( getDashboardMenuContent() );
           }
       } );
    

    您应该注意Hyperlink.addClickHandler(...) 已被弃用,建议使用Anchor.addClickHandler(...)。

    至于其他问题:使用 UIBinder 构建 UI 更优雅、更容易,所以一定要研究一下,但请先尝试让“它”工作,以避免 .ui.xml 设置增加的复杂性:-)

    干杯,

    【讨论】:

    • 感谢@Anders Rostgaard Bystru (+1) - 我特别欣赏代码示例(帮助我将其可视化)!关于 UiBinder 的一个快速跟进:我知道是否使用它是一个偏好问题。我想我正在努力可视化如何在这里使用 UiBinder。我不确定我是否应该为每个小部件(H1 和 H$ 标签、3 个菜单、menuContent 面板)设置单独的 UiBinder sn-ps(XMLs?),还是只为整个“页面”设置一个大的。再次感谢!
    • 没有问题。这又是一个见仁见智的问题 :-) 对于相对简单的页面,我推荐一个 UiBinder 并在其中使用 Panel's 来放置您的小部件。一旦您进行更复杂的设置,您可以轻松地将 UIBinder 包含在父 UIBinders 中的面板中。
    • 我还推荐使用 UI Binder。它确实删除了大量的样板代码。试一试;)
    【解决方案3】:

    我有一个简单的建议要给你。使用框架提供的功能。

    HTML 小部件应该是您最后的转义。小部件太多了,您几乎不需要在代码中的任何地方编写 html。

    因此,您可以使用以下代码代替 headerBuilder

    Label header = new Label("MyWebApp");
    header.setStyleName("headerStyle",true);
    

    您可以在外部 Css 文件中设置样式属性,并在基本 html 文件或 gwt.xml 文件中添加引用。这样就回答了你关于mainPanel.add(new HTML(headerBuilder.toSafeHtml().toString()));的问题

    关于超链接。如果您选择使用超链接,请记住最有效的用法是使用更广为人知的位置和活动(网络上的大量信息)的 MVP 模式

    如果您想要更简单的东西,MenuBar 和 MenuItem 类应该可以解决问题。

    查看here 以获取有关如何使用MenuBar 来控制您的应用程序的示例。还有很多其他方法,但为什么不使用提供的工具呢?

    另外,UIBinder 与 Designer/Classes 方法在 stackoverflow 上进行了广泛讨论,导致选择和编程熟悉度/偏好问题。

    【讨论】:

    • 感谢@Thanos K. (+1) - 我仍然有点模糊/困惑:(1) Label 的 JavaDocs 说它应该与以下内容一起使用 不 意味着被解释为 HTML。那么这与我使用&lt;h1&gt; 和&lt;hr&gt; 标签的愿望有什么关系呢? (2) 如果 UiBinder“框架”(XML、注释、类型等)真的只是我上面使用的“标准”框架的替代,它是否提供任何性能/安全/效率优势,还是仅适用于面向 HTML 的人?我问是因为我来自 Swing 背景所以 UiBinder 框架...
    • (续上)...实际上对我来说比小部件/面板/POJO 更难理解。除非有充分的理由,例如性能或安全性,否则我不想使用 UiBinder。再次感谢!
    • 我认为 javadoc 所说的是,您不应该在 Label 内编写 HTML,只是您希望它显示的内容。至于 UI Binder,它要快一些,而且最新的 GWT Designer 支持它,所以如果你使用 Eclipse,你不需要学习很多东西。它还以更清晰的方式将 View 与 Presenter 和 Model 分开。当我想使用和制作自定义单元格时,我个人从不使用视图保存中的 html 标记
    • 啊,所以澄清一下:您是说在 GWT 领域中很少在 HTML 标记(如 H1 和 HR 标记)中编码是“正常的”……您是说 GWT 提供抽象所有这些的小部件,我应该使用 Widget 库还是使用 UiBinder?如果是这样,那么作为一名前 Swing 开发人员,我的理念可能是:使用 Widgets API,除非您需要 Widgets 不提供的东西。然后,并且只有在那时,才使用 UiBinder。 这听起来像一个体面的游戏计划吗?
    • 我知道这些问题是模糊的/主观的,但我一个人在这里编写代码,我想不出一个更好的社区来问这些“我做这件事吗?”类型的问题。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2011-02-22
    • 2017-11-13
    • 1970-01-01
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多