gwt - tutorial - stockwatcher




Tutorial de páginas múltiples en Google Web Toolkit(GWT) (6)

Acabo de empezar a aprender Google Web Toolkit (GWT). ¿Cómo hago diferentes páginas HTML en mi aplicación GWT?

Por ejemplo, quiero crear una aplicación para una librería. En esta aplicación tendré tres páginas:

  1. Páginas de inicio donde daré la bienvenida al usuario y ofreceré libros de usuario
  2. Página para buscar libros por categorías y ver detalles (usar widgets GWT)
  3. Echa un vistazo a los libros en línea.

Por supuesto, podría haber otras páginas como los detalles del usuario, agregar un nuevo libro, etc. Entonces, ¿cuál es la mejor manera de hacer diferentes páginas en GWT y cómo puedo hacer la navegación de una página a otra? ¿Hay algún ejemplo o tutorial? ¿O incluso necesito crear páginas diferentes cuando puedo crear una aplicación completa en una página?


¡Increíble! Combiné la respuesta de Chris R. con la de Chris Boesing para llegar a esto:

Esta es la página de inicio de 'índice'

public class Index implements EntryPoint, ValueChangeHandler<String> {
    public void onModuleLoad() {
        History.addValueChangeHandler(this);
        if (History.getToken().isEmpty()) History.newItem("index");
        Composite c = new Login(); 
        FlowControl.go(c);
    }

    public void onValueChange(ValueChangeEvent<String> e) {
        FlowControl.go(History.getToken());
    }
}

Este es el controlador o ContentContainer según Chris R.

public class FlowControl {
private static FlowControl instance;
private FlowControl() {}
public static void go(Composite c) {
    if (instance == null) instance = new FlowControl(); // not sure why we need this yet since everything is static.
    RootPanel.get("application").clear();
    RootPanel.get("application").getElement().getStyle().setPosition(Position.RELATIVE); // not sure why, but GWT throws an exception without this. Adding to CSS doesn't work.
    // add, determine height/width, center, then move. height/width are unknown until added to document. Catch-22!
    RootPanel.get("application").add(c);
    int left = Window.getClientWidth() / 2 - c.getOffsetWidth() / 2; // find center
    int top = Window.getClientHeight() / 2 - c.getOffsetHeight() / 2;
    RootPanel.get("application").setWidgetPosition(c, left, top);
    History.newItem(c.getTitle()); // TODO: need to change and implement (or override) this method on each screen
}

public static void go(String token) {
    if (token == null) go(new Login());
    if (token.equals("cart")) go(new Cart());
    if (token.equals("login")) go(new Login());
    // Can probably make these constants in this class
}

Luego puede presionar hipervínculos y botones en cualquier parte de su código. (Todavía no he probado los hipervínculos).

    Button submit = new Button("Submit");
    submit.addClickHandler(new ClickHandler() {
        public void onClick(ClickEvent event) {
            FlowControl.go(new MyScreen());             
        }           
    });

Agregué un div a mi HTML

<!-- This is where the application will reside within. It is controlled by FlowControl class. -->
<div id="application"></div>

Y ahora todas las pantallas deben llamar a initWidget () en el constructor en lugar de agregar a RootPanel, ya que ahora es una clase compuesta, como

    initWidget(myPanel); // all composites must call this in constructor

Agregue un módulo para cada página que tenga que necesita la funcionalidad GWT. Reutiliza tus componentes.


Si quieres que esté COMPLETO AJAXified (como una aplicación de escritorio), por supuesto, solo necesitarás una página. Luego solo cambia el contenido del cuerpo dependiendo del enlace.

Además, hay un grupo de google para GWT que está muy activo, y sé que esto se ha preguntado antes, solo necesitas usar la función "buscar".


Usaría la clase HyperLink y History. Lo bueno de la clase Hyperlink es que establece este token (por ejemplo, # foobar), y todo lo que tiene que hacer es capturar el evento, que se dispara cuando se cambia el valor del token (ValueChangeEvent). En el manejador de sucesos, usted reemplazaría las páginas.

Ejemplo: dirección de la página de bienvenida: www.yourpage.com/#home en esta página sería un enlace a la página "browse book", cuando se hace clic en el enlace, la nueva dirección sería algo como esto: www.yourpage.com /#vistazo

Y aquí está el código:


public class MainEntryPoint implements EntryPoint, ValueChangeHandler {
    VerticalPanel panel = new VerticalPanel();
    Label label=new Label();
    public void onModuleLoad() {
        Hyperlink link1 = new Hyperlink("books", "browse");
        Hyperlink link2 = new Hyperlink("user details", "details");
        panel.add(link1);
        panel.add(link2);
        panel.add(label);
        RootPanel.get().add(panel);
        History.addValueChangeHandler(this);
        //when there is no token, the "home" token is set else changePage() is called.
        //this is useful if a user has bookmarked a site other than the homepage.
        if(History.getToken().isEmpty()){
            History.newItem("home");
        } else {
            changePage(History.getToken());
        }
    }

public void onValueChange(ValueChangeEvent event) {
    changePage(History.getToken());
}
public void changePage(String token) {
    if(History.getToken().equals("browse")) {
        label.setText("Here would be some books");
    } else if (History.getToken().equals("details")) {
        label.setText("Here would be the user details");
    } else {
        label.setText("Welcome page");
    }
}

}


GWT Multipage : marco simple para aplicaciones GWT de varias páginas.


Lo que suelo hacer en situaciones como esta es diseñar primero el marco de la página web. Tendré un div para el encabezado, el menú lateral y el pie de página. También tendré un div en mi HTML para el contenido principal.

Ejemplo:

<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta name='gwt:module' content='org.project.package.Core=org.project.package.Core'>
    </head>
    <body>
        <!-- Load the JavaScript code for GWT -->
        <script language="javascript" src="ui/org.project.package.ui.Core.nocache.js"></script>

        <!-- For some unknown reason in Internet Explorer you have to have cellpadding/spacing ON THE ELEMENT and not on the STYLE if it is in the body tag like this -->
        <table id="wrapper" cellpadding="0" cellspacing="0" style="width: 100%;height: 100%;">

             <!-- Header row -->
             <tr style="height: 25%;">
                 <td colspan="2" id="header"></td>
             </tr>

             <!-- Body row and left nav row -->
             <tr style="height: 65%;">
                 <td id="leftnav"></td>
                 <td id="content"></td>
             </tr>

             <!-- Footer row -->
             <tr style="height: 10%;">
                <td colspan="2" id="footer"></td>
             </tr>

        </table>

        <!-- This iframe handles history -->
        <iframe id="__gwt_historyFrame" style="width:0;height:0;border:0"></iframe>
    </body>
</html>

(Si le gustan los diseños basados ​​en <div>, puede usarlos en su lugar).

Luego construyes tu punto de entrada (en mi caso Core.java ) como lo harías normalmente, configurando cada uno de los elementos según sea necesario.

RootPanel.get("header").add(new Header());
RootPanel.get("leftnav").add(new NavigationMenu());
RootPanel.get("footer").add(new Footer());

Por supuesto, es posible tener un pie de página y un encabezado estáticos, pero eso no es ni aquí ni allí.

También tengo una clase abstracta llamada "Contenido". Los objetos de contenido extienden "Compuesto" y tendrán varios métodos para simplificar la creación y el diseño de una nueva página. Cada página que construyo para esta aplicación, ya sea una pantalla de ayuda, una pantalla de búsqueda, un carrito de compras o cualquier otra cosa, es de tipo Content .

Ahora, lo que hago es crear una clase llamada "ContentContainer". Este es un singleton que es responsable de administrar el elemento "contenido". Tiene un método "setContent" que acepta objetos de tipo "Contenido". A continuación, básicamente elimina cualquier cosa dentro del "contenido" <td> y lo reemplaza con cualquier widget (compuesto) que asigne mediante el método "setContent". El método setContent también maneja el historial y la administración de la barra de título. Básicamente, ContentContainer sirve para agregar todos los diversos puntos de enlace que podría tener que hacer si el contenido de cada página tuviera que "conocer" todas las funciones que debe realizar.

Finalmente, necesitas una forma de llegar a esa página, ¿verdad? Así de simple:

ContentContainer.getInstance().setContent(new Search());

Ponga lo anterior en un evento de clic en algún lado y estará dorado.

Las únicas cosas a las que deben atarse sus otros widgets son ContentContainer y el tipo de contenido que están agregando.

Las desventajas que puedo ver al enfoque de ChrisBo son que tienes una lista que debe mantenerse de tokens -> páginas. El otro inconveniente que puedo ver es que no veo cómo se puede tener un sistema de historia real con este método.

Una cosa que sí ofrece sobre mi enfoque es que todas las opciones de página están bastante centralizadas. Usaría algún tipo de Enum o al menos una clase estática con valores String para evitar que se enreden los enlaces.

En cualquier caso, creo que el punto se puede resumir de la siguiente manera: intercambie el contenido de un elemento central de la página en función de las acciones que haga su usuario y las acciones que realice su (s) usuario (s).