【问题标题】:How do you create multiple pages in GWT?如何在 GWT 中创建多个页面?
【发布时间】:2013-09-30 18:06:56
【问题描述】:

我有一个登录页面和主页。登录后,我有

    public void onSuccess(String result) {
        // go to the next page
        SDM_Mailer page = new SDM_Mailer();
        RootPanel.get().remove(0);
        RootPanel.get().add(page);
    }

但是 RootPanel 不接受 EntryPoint 对象! add() 只接受一个小部件!好的,所以我扩展了 Widget

公共类 SDM_Mailer 扩展 Widget 实现 EntryPoint {

但是现在当我尝试在 GWT 设计器中编辑 SDM_Mailer 时,它给出了这个错误:

那么究竟如何创建多个页面,而不是全部在同一个巨大的类文件中或使用选项卡?我知道我以前做过,但不记得了,而且是旧版本。

【问题讨论】:

    标签: java gwt


    【解决方案1】:

    您可以采用活动和地点

    如官方gwt project site所说:

    Activity 和 Places 框架允许您在应用程序中创建可添加书签的 URL,从而允许浏览器的后退按钮和书签按用户期望的方式工作。

    活动

    活动只是代表用户正在做的事情。 Activity 不包含 Widget 或 UI 代码。

    地点

    地点是代表 UI 特定状态的 Java 对象。地点可以与 URL 历史令牌相互转换

    来源:http://www.gwtproject.org/doc/latest/DevGuideMvpActivitiesAndPlaces.html

    【讨论】:

      【解决方案2】:

      您通常只有一个EntryPoint,您可以从那里添加不同的小部件(可以代表您的不同页面)并管理它们。

      一个非常简单的方法是,对于一个小应用程序,可以在代表页面的不同小部件上使用.setVisible(true)setVisible(false),但从长远来看,这不是一个好方法。

      您还可以有一个容器小部件,您可以在其中添加您想要显示的任何小部件,然后当您想在其中放置一个新小部件时将其清除。

      container.clear();
      container.add(widget)
      

      上述建议适用于小型应用程序,但当您的应用程序有很多页面(视图)时就不是很好了。管理页面(视图)的一种流行方法是使用MVP Activities and Places。虽然开销很大,但可扩展且运行良好。

      【讨论】:

      • 只是出于好奇,您认为隐藏/可见解决方案是否安全?例如,我可以想象没有登录的人,只需更改 html 属性并可以访问页面的授权版本。你有什么看法?
      • 这取决于您如何授予对小部件的访问权限。如果它纯粹是通过 URL,那么它可能是一个安全问题。但是您需要做的就是在设置视图之前检查权限。 .clear()/.add() 或 MVP 活动和地点基本上是相同的问题。在使任何视图可见之前,您需要检查权限。
      • @fascynacja 这绝对不安全,但是你的整个应用程序会被下载开始,如果用户确定,可以反编译所有的 Javascript。始终在服务器端验证每个操作的身份验证和凭据。这个答案并没有真正解决分离多个页面并在设计器中在单独的文件中编辑它们。您不能只使用 Widget 类,因为设计器不会加载 Widget。
      【解决方案3】:

      扩展小部件不会神奇地使某些东西在 HTML 中可表示。小部件在 HTML 中提供了某些东西的图形表示,也就是说,一种将自己呈现为 HTML 的方式,这通常通过实现 UIBinders 来实现。我强烈建议您采用 MVP 方法并使用活动、地点和视图。查看official documentation 了解如何操作,它比您想象的要简单。

      如果您使用 Eclipse,the GWT plugin 会完成大部分样板文件。使用方法可以看this video

      【讨论】:

        【解决方案4】:

        这就是我最终做的:

        package com.example.client;
        
        import java.util.logging.Logger;
        
        import com.google.gwt.core.client.EntryPoint;
        import com.google.gwt.core.shared.GWT;
        import com.google.gwt.event.logical.shared.ValueChangeEvent;
        import com.google.gwt.event.logical.shared.ValueChangeHandler;
        import com.google.gwt.user.client.History;
        import com.google.gwt.user.client.ui.RootPanel;
        
        public class Controller implements EntryPoint {
            private static Controller instance;
            private static final Logger log = Logger.getLogger(Controller.class.getName());
        
            // I have a feeling GWT does not respect private constructors, or else it uses some other voodoo.
            private Controller(){}
        
            public static Controller getInstance() {
                if (instance == null) instance = new Controller();
                return instance;
            }
        
            @Override
            public void onModuleLoad() {
                String token = History.getToken();
                log.info("****************************** token:"+token);
                History.addValueChangeHandler(new ValueChangeHandler<String>() {
                    @Override
                    public void onValueChange(ValueChangeEvent<String> event) {
                        navigate(event.getValue());
                    } // onValueChange
                });
                if (token == null || token.length() == 0) History.newItem(Login.TOKEN); // no token
                else navigate(token); // restore app state
            }
        
            private static void navigate(String token) {
                RootPanel rootPanel = RootPanel.get("gwtApp");
                if (rootPanel.getWidgetCount() > 0) rootPanel.remove(0); // clear the page
        
                if (Login.TOKEN.equals(token)) {
                    Login page = Login.getInstance();
                    page.onModuleLoad();
                } else if (MainApp.TOKEN.equals(token)) {
                    MainApp page = MainApp.getInstance();
                    page.onModuleLoad(); // display the page
        //          page.setAuthenticated(true);
        //          page.setUsername(email);
                }
        
            }
        
        } // Controller
        

        在您的 *.gwt.xml 文件中:

        <entry-point class='com.example.client.Controller' /> 
        

        现在当你想去一个新的页面时:

        History.newItem(Login.TOKEN);
        

        这似乎很熟悉,可能是我几年前想出的。

        【讨论】:

        • 你为什么要这样做?这不是假设使用 GWT 的方式。应该只有一个EntryPoint。 Ypu 真的应该使用 MVP。
        • 这正是 GWT 应该被使用的方式。历史在文档中。否则,Google 插件会提供一个下拉菜单来“创建新的 GWT 页面”,它会自动添加所有样板,并且可以在 GWT Designer 中进行编辑,并且在入门指南中会有一个简单的多页示例。鉴于这些都不存在,Google 希望您制作自己的控制器和导航框架。它与 Rails 非常不同。
        猜你喜欢
        • 2014-07-02
        • 2021-03-27
        • 2017-05-19
        • 2017-11-17
        • 2014-07-20
        • 1970-01-01
        • 1970-01-01
        • 2013-06-05
        • 2011-04-06
        相关资源
        最近更新 更多