Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

CreatingABookmarkableApplicationWithBackButtonSupport.asciidoc 5.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. ---
  2. title: Creating A Bookmarkable Application With Back Button Support
  3. order: 81
  4. layout: page
  5. ---
  6. [[creating-a-bookmarkable-application-with-back-button-support]]
  7. = Creating a bookmarkable application with back button support
  8. Vaadin 7 comes with a new set of APIs to aid creation of navigation
  9. within your application. The main concepts are *Navigator* and *View*,
  10. and using these you can easily create an application that supports the
  11. standard browser methods for navigation; bookmarking, history, back- and
  12. forward navigation using browser buttons. This is (usually) done using
  13. browser "fragments" (the stuff after the #-character in the URI).
  14. At the same time, the API provides a natural way of partitioning your
  15. application into views - something most applications did previously
  16. anyway, but previously without framework 'guidance'.
  17. Let's start by making a View that counts the times it has been created.
  18. This is a simple example, but will later shed some light on when Views
  19. are created, but let's not worry about that just yet:
  20. [source,java]
  21. ....
  22. import com.vaadin.navigator.View;
  23. import com.vaadin.ui.Label;
  24. import com.vaadin.ui.Panel;
  25. public class CountView extends Panel implements View {
  26. public static final String NAME = "count";
  27. private static int count = 1;
  28. public CountView() {
  29. setContent(new Label("Created: " + count++));
  30. }
  31. public void enter(ViewChangeEvent event) {
  32. }
  33. }
  34. ....
  35. We'll extend Panel as a convenient base, and add a Label to that in the
  36. constructor, updating the static count. The _enter()_ -method comes from
  37. View, and is called when our View is activated, but we'll do nothing
  38. about that in our simplistic View.
  39. Note the _static final NAME_: we'll use it instead of a 'magic' string
  40. when we register the View with the Navigator later. Feel free to use any
  41. method you like to keep track of your View-names (e.g Enum, simpleName
  42. of the View's class, and so on…)
  43. In order to do any navigating, we'll need at least two views, so let's
  44. create a main view that has a link to the counting view we just created.
  45. [source,java]
  46. ....
  47. import com.vaadin.navigator.View;
  48. import com.vaadin.server.ExternalResource;
  49. import com.vaadin.ui.Link;
  50. import com.vaadin.ui.Panel;
  51. public class MainView extends Panel implements View {
  52. public static final String NAME = "";
  53. public MainView() {
  54. Link lnk = new Link("Count", new ExternalResource("#!"
  55. + CountView.NAME));
  56. setContent(lnk);
  57. }
  58. public void enter(ViewChangeEvent event) {
  59. }
  60. }
  61. ....
  62. Note the empty string used as _NAME_. This is because we want this to be
  63. our main ("home") View, displayed before any navigation is done.
  64. In this example we use a Link and let the browser do the navigating. We
  65. could just as easily use a Button and tell the Navigator where we want
  66. to go when the button's ClickListener is invoked. Note that we're using
  67. _CountView.NAME_, and what we're actually doing is using the "fragment"
  68. part of the application URI to indicate the view. The resulting URI will
  69. look something like http://.../application#count .
  70. Ok, one last thing: we need to set up a UI with a Navigator, and
  71. register our views:
  72. [source,java]
  73. ....
  74. import com.vaadin.navigator.Navigator;
  75. import com.vaadin.navigator.Navigator.SimpleViewDisplay;
  76. import com.vaadin.server.Page;
  77. import com.vaadin.server.WrappedRequest;
  78. import com.vaadin.ui.UI;
  79. public class NavigationtestUI extends UI {
  80. @Override
  81. public void init(VaadinRequest request) {
  82. // Create Navigator, use the UI content layout to display the views
  83. Navigator navigator = new Navigator(this, this);
  84. // Add some Views
  85. navigator.addView(MainView.NAME, new MainView()); // no fragment
  86. // #count will be a new instance each time we navigate to it, counts:
  87. navigator.addView(CountView.NAME, CountView.class);
  88. // The Navigator attached to the UI will automatically navigate to the initial fragment once
  89. // the UI has been initialized.
  90. }
  91. }
  92. ....
  93. There are advanced ways to use the Navigator API, and there are simple
  94. ways. Most applications will do fine with the simple ways, and the
  95. Navigator constructor we used is written that in mind. It simply takes
  96. any ComponentContainer, assumes that all our Views are also Components,
  97. and on a view change sets the given view as the ComponentContainer's
  98. only child. Internally, it uses a _ViewDisplay_ subclass called
  99. ComponentContainerViewDisplay to do this. If we had more advanced
  100. requirements, we could write our own ViewDisplay subclass to show our
  101. views in whatever fashion we'd like.
  102. The Navigator finds out about URI fragment changes through the Page, and
  103. directs the ViewDisplay accordingly. We register our Views using
  104. _addView()_ so that the Navigator knows how to connect fragments with
  105. Views. Again notice how we use the static NAME instead of
  106. _addView("name", view)_ - but feel free to use other approaches.
  107. In order to illustrate how the two differ, we register an _instance_ of
  108. the MainView, but _CountView.class_. As a result, the MainView is
  109. created once, when the UI is created, and lives as long as the UI lives.
  110. On the other hand, a new CountView instance will be created each time we
  111. navigate to it (but no earlier). You can try navigating back-and-forth
  112. and see how the count is updated - try registering it using new
  113. CountView() instead…
  114. It's also good to keep in mind that a new UI is created each time you
  115. press reload in the browser, unless you use the @PreserveOnRefresh
  116. annotation on the UI.