Diese Präsentation wurde erfolgreich gemeldet.

Wicket 2010

6

Teilen

Nächste SlideShare
Apache Wicket Web Framework
Apache Wicket Web Framework
Wird geladen in …3
×
1 von 150
1 von 150

Wicket 2010

6

Teilen

Presentation about Apache Wicket given at FOSDEM 2011. Apache Wicket is an open source, component oriented Java web framework. This presentation features an introduction to the Wicket framework and showcases some of the new features in the upcoming 1.5 release of Wicket.

Presentation about Apache Wicket given at FOSDEM 2011. Apache Wicket is an open source, component oriented Java web framework. This presentation features an introduction to the Wicket framework and showcases some of the new features in the upcoming 1.5 release of Wicket.

Weitere Verwandte Inhalte

Ähnliche Bücher

Kostenlos mit einer 14-tägigen Testversion von Scribd

Alle anzeigen

Ähnliche Hörbücher

Kostenlos mit einer 14-tägigen Testversion von Scribd

Alle anzeigen

Wicket 2010

  1. Introducing Apache Wicket Martijn Dashorst
  2. Agenda • Introduction to Apache Wicket • New and noteworthy in 1.5 • Questions
  3. Martijn Dashorst • Employee @ Topicus • Chair for Apache Wicket • Committer • Apache Member • Author Wicket in Action
  4. Introduction
  5. Wicket is... a component oriented web framework using just HTML and Java
  6. Apache Wicket • Open Source: ASL 2.0 • Created in 2004 • Java web framework • Component oriented • http://wicket.apache.org
  7. Who’s using Wicket?
  8. mobile.walmart.com supports three categories of devices using the same Java code (only the html is (very) different.) Try doing that with JSP. — Joachim Kainz
  9. ... We at Vegas.com have been able to re- purpose our Wicket-based air/hotel search application and purchase/checkout application. This is the new mexico.com. [...] The re-use of components and abstract pages was tremendous. —Scott Swank, chief architect vegas.com
  10. Just HTML
  11. Sign up form Example from Railscast episode #250
  12. Sign up form
  13. Sign up form <h1>Sign Up</h1> <form> <div class="error_messages"> <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input type="email" id="email" /> </p> <p> <label for="password">Password</label> <input type="password" id="password" /> </p> <p> <label for="confirm">Password confirmat <input type="password" id="confirm" /> </p> <p class="button"><input type="submit" va
  14. Sign up form
  15. Sign up form <h1>Sign Up</h1>      <%= form_for @user do |f| %>     <% if @user.errors.any? %>       <div class="error_messages">         <h2>Form is invalid</h2>         <ul>           <% for message in @user.errors.full             <li><%= message %></li>           <% end %>         </ul>       </div>     <% end %>     <p>       <%= f.label :email %><br />       <%= f.text_field :email %>     </p>     <p>       <%= f.label :password %><br />       <%= f.password_field :password %>     </p>     <p>
  16. Sign up form <h1>Sign Up</h1> <form> <div class="error_messages"> <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input type="email" id="email" /> </p> <p> <label for="password">Password</label> <input type="password" id="password" /> </p> <p> <label for="confirm">Password confirmat <input type="password" id="confirm" /> </p> <p class="button"><input type="submit" va
  17. Sign up form <h1>Sign Up</h1> <form> <div wicket:id="feedback" class="error_me <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input wicket:id="email" type="email" i </p> <p> <label for="password">Password</label> <input wicket:id="password" type="passw </p> <p> <label for="confirm">Password confirmat <input wicket:id="confirm" type="passwo </p> <p class="button"><input type="submit" va
  18. Sign up form <h1>Sign Up</h1> <form> <div wicket:id="feedback" class="error_me <h2>Form is invalid</h2> <ul> <li>Some error message</li> </ul> </div> <p> <label for="email">E-Mail</label><br/> <input wicket:id="email" type="email" i </p> <p> <label for="password">Password</label> <input wicket:id="password" type="passw </p> <p> <label for="confirm">Password confirmat <input wicket:id="confirm" type="passwo </p> <p class="button"><input type="submit" va
  19. <tag wicket:id="foo"> Instructs Wicket to work on this tag
  20. Imperative markup <h1>Sign Up</h1> • Used by Ruby on Rails, <%= form_for @user do |f| %>   <% if @user.errors.any? %> JSP, Play, Velocity, ...     <div class="error_messag       <h2>Form is invalid</h •       <ul> Great for web developers         <% for message in @u           <li><%= message %> • Great for hacking on a         <% end %>       </ul> web site     </div>   <% end %>   <p> • Code and markup are     <%= f.label :email %><br     <%= f.text_field :email  not separated   </p>   <p>
  21. Declarative markup <h1>Sign Up</h1> • Used by Wicket, Tapestry, <form wicket:id="form"> <div class="error_message Facelets <p> <label for="email">E-Ma • Great for web designers <input type="email" id= </p> <p> • Go from PSD → HTML → <label for="password">P <input type="password" Page → Component </p> <p> <label for="confirm">Pa • Code and markup are <input type="password" </p> strictly separated <p class="button"><input </form>
  22. Just Java
  23. Sign up form <h1>Sign Up</h1>      <%= form_for @user do |f| %>     <% if @user.errors.any? %>       <div class="error_messages">         <h2>Form is invalid</h2>         <ul>           <% for message in @user.errors.full_messages %>             <li><%= message %></li>           <% end %>         </ul>       </div>     <% end %>     <p>       <%= f.label :email %><br />       <%= f.text_field :email %>     </p>     <p>       <%= f.label :password %><br />       <%= f.password_field :password %>     </p>     <p>       <%= f.label :password_confirmation %>  
  24. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form);
  25. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback);
  26. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true));
  27. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true)); form.add(new PasswordField("password", Model.of("")) .setRequired(true));
  28. Sign up form Form form = new Form("signup") { @Override public void onSubmit() { // ... } } add(form); FeedbackPanel feedback = new FeedbackPanel("feedback"); feedback.setVisible(form.hasFeedbackMessages()); form.add(feedback); form.add(new EmailTextField("email", Model.of("")) .setRequired(true)); form.add(new PasswordField("password", Model.of("")) .setRequired(true)); form.add(new PasswordField("confirm", Model.of("")) .setRequired(true));
  29. Just Java • No logic in markup • Components are objects (use new and extends) • Use OO techniques in your programming • No XML
  30. Concepts
  31. Components • Manipulate markup • Render content • Receive events (onClick, onSubmit) • Examples: Label, Link, Form, TextField, PagingNavigator, Panel, Page, ClientSideImageMap
  32. Models • Provide data to components • Store data for components • Transform data • Retrieve data from persistent storage • Examples: Model<T>, PropertyModel<T>
  33. Behaviors • Decorator/Adapter for Component • Can manipulate markup of Component • Can receive events (onClick) • Add Ajax functionality to components • Example: AjaxSelfUpdatingTimerBehavior
  34. Getting started
  35. Wicket projects • Apache Wicket • Leg before Wicket (extensions, spring, guice, velocity, etc) (Maven archetypes) • Wicket stuff • Apache Isis (grand collection of projects) (incubating, DDD framework) • Seam for Apache • Jolira Tools Wicket (powers mobile.walmart.com) • WiQuery • Visural Wicket (standalone Wicket components) (JQuery integration library)
  36. Apache Wicket projects • Core • Velocity • Extensions • Auth/Roles • Quick start • JMX • IoC • Dev utils • Spring • Guice • Examples • DateTime
  37. Wicket Stuff projects • progressbar • shiro-security • theme • datatable-autocomplete • gae-initializer • yav • flot • push-jdk-1.5 • maven-support • googlecharts • jasperreports • plugin • scala-extensions • mbeanview • input-events • openlayers • jsr303 • javaee-inject • gmap2 • client-and-server-validation • push • inmethod-grid • multi-text-input • wicket-html5 • minis • prototype • wicket-servlet3 • phonebook • simile-timeline
  38. Quick start
  39. Quick start
  40. Running quickstart $_
  41. Running quickstart $ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket - DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5- SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject - DarchetypeRepository=https://repository.apache.org/content/repositories/ snapshots/ -DinteractiveMode=false _
  42. Running quickstart $ mvn -o archetype:generate -DarchetypeGroupId=org.apache.wicket - DarchetypeArtifactId=wicket-archetype-quickstart -DarchetypeVersion=1.5- SNAPSHOT -DgroupId=com.mycompany -DartifactId=myproject - DarchetypeRepository=https://repository.apache.org/content/repositories/ snapshots/ -DinteractiveMode=false [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building Maven Stub Project (No POM) 1 [INFO] ----------------------------------------------------------- [INFO] >>> maven-archetype-plugin:2.0:generate (default-cli) >>> [INFO] <<< maven-archetype-plugin:2.0:generate (default-cli) <<< [INFO] --- maven-archetype-plugin:2.0:generate (default-cli) --- [INFO] Generating project in Batch mode [INFO] Archetype defined by properties [INFO] ----------------------------------------------------------- [INFO] BUILD SUCCESS [INFO] ----------------------------------------------------------- [INFO] Total time: 1.279s [INFO] Finished at: Fri Feb 04 22:04:14 CET 2011 [INFO] Final Memory: 9M/81M [INFO] -----------------------------------------------------------
  43. Running quickstart $ mvn jetty:run_
  44. Running quickstart $ mvn jetty:run [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building quickstart 1.0-SNAPSHOT [INFO] ----------------------------------------------------------- [INFO] Starting jetty 7.2.2.v20101205 ... 2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205 2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo INFO - WebXmlFile - web.xml: found filter with na INFO - Application - [wicket.myproject] init: Wick INFO - RequestListenerInterface - registered listener interface INFO - WebApplication - [wicket.myproject] Started Wi ****************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. *** *** ^^^^^^^^^^^ *** *** Do NOT deploy to your live server(s) without changing this.*** *** See Application#getConfigurationType() for more information*** ****************************************************************** 2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
  45. Running quickstart
  46. Quick start alternative Leg up • Spring • Guice • JDBC • JPA • Hibernate • Scala http://jweekend.com/dev/LegUp
  47. Want to learn more?
  48. Want to learn more?
  49. Want to learn more? http://wicket.apache.org/learn/books.html
  50. Examples
  51. Examples Hello, World!
  52. Hello, World! <h1>Hello, World</h1>
  53. Hello, World! <h1>[Replaced text]</h1>
  54. Hello, World! <h1 wicket:id="msg">[Replaced text]</h1>
  55. Hello, World! <h1 wicket:id="msg">[Replaced text]</h1> + add(new Label("msg", "Hello, World!"));
  56. Hello, World! <h1 wicket:id="msg">[Replaced text]</h1> + add(new Label("msg", "Hello, World!")); = <h1>Hello, World!</h1>
  57. Examples Click counter
  58. This link has been clicked 123 times
  59. This link has been clicked 123 times This link has been clicked 123 times!
  60. This link has been clicked 123 times This <a href="#">link</a> has been clicked 123 times!
  61. This link has been clicked 123 times This <a href="#">link</a> has been clicked <span>123</span> times!
  62. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span>123</span> times!
  63. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span wicket:id="clicks">123</span> times!
  64. This link has been clicked 123 times This <a wicket:id="link" href="#">link</a> has been clicked <span wicket:id="clicks">123</span> times!
  65. This link has been clicked 123 times public class ClickCountPage extends WebPage { }
  66. This link has been clicked 123 times public class ClickCountPage extends WebPage { public ClickCountPage() { } }
  67. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { } }
  68. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { add(new Link<Void>("link") { public void onClick() { clicks++; } }); }
  69. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCountPage() { add(new Link<Void>("link") { ... }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks"))); } }
  70. Wicket for developers
  71. 2 modes for your app Development and Deployment
  72. Development mode $ mvn jetty:run [INFO] Scanning for projects... [INFO] ----------------------------------------------------------- [INFO] Building quickstart 1.0-SNAPSHOT [INFO] ----------------------------------------------------------- [INFO] Starting jetty 7.2.2.v20101205 ... 2011-02-04 22:04:34.969:INFO::jetty-7.2.2.v20101205 2011-02-04 22:04:35.198:INFO::No Transaction manager found - if yo INFO - WebXmlFile - web.xml: found filter with na INFO - Application - [wicket.myproject] init: Wick INFO - RequestListenerInterface - registered listener interface INFO - WebApplication - [wicket.myproject] Started Wi ****************************************************************** *** WARNING: Wicket is running in DEVELOPMENT mode. ** *** ^^^^^^^^^^^ ** *** Do NOT deploy to your live server(s) without changing this. ** *** See Application#getConfigurationType() for more information ** ****************************************************************** 2011-02-04 22:04:35.464:INFO::Started SelectChannelConnector@0.0.0.0:8080 [INFO] Started Jetty Server
  73. Development mode • exceptional error pages • dynamic markup reloading • no caching • no javascript/css optimizations • discover mistakes early (serialization, missing components, ...) • Wicket debugger visible
  74. Deployment mode • Cache markup resources • No checks • Don’t display stack traces to users • Minimize/compress JavaScript • Don’t generate wicket tags • Wicket debugger not visible
  75. FREE PRO TIP: Don’t perform your performance tests in development mode!
  76. Ajax debugger
  77. Ajax debugger
  78. Ajax envelope <?xml version="1.0" encoding="UTF-8"?> <ajax-response> <component id="count2"> <![CDATA[<span wicket:id="count" id="count2">1</span>]]> </component> </ajax-response>
  79. Error message Unable to find component with id 'count' in HomePage. This means that you declared wicket:id=count in your markup, but that you either did not add the component to your page at all, or that the hierarchy does not match.
  80. Error pages
  81. Testing the UI
  82. WicketTester • Test components directly, or their markup • Runs tests without starting server • Ajax testing (server side) • Runs in IDE, ant, maven builds • Achieves high code coverage
  83. Testing Hello, World! @Test public void rendersWelcomeMessage() { }
  84. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); }
  85. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorldPage.class); }
  86. Testing Hello, World! @Test public void rendersWelcomeMessage() { WicketTester tester = new WicketTester(); tester.startPage(HelloWorldPage.class); tester.assertLabel("msg", "Hello, World!"); }
  87. Testing Click Count @Test public void clicksIncreaseCount() { }
  88. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); }
  89. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); }
  90. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); }
  91. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); tester.clickLink("link"); }
  92. Testing Click Count @Test public void clicksIncreaseCount() { WicketTester tester = new WicketTester(); tester.startPage(ClickCountPage.class); tester.assertModelValue("clicks", 0); tester.clickLink("link"); tester.assertModelValue("clicks", 1); }
  93. Other test frameworks • PageTest (by Kent Tong) • JDave (BDD framework)
  94. Summary • Widely used • Component oriented • Java • Open Source (ASL 2.0)
  95. What’s new in 1.5?
  96. HTML 5 support
  97. Pre 1.5 • Checks for valid markup don’t accept new field types • HTML 5 defines: <input type=”text|email|password|number|date| search|url|...”>
  98. Wicket 1.5 • EmailTextField • NumberTextField • UrlTextField • RangeTextField
  99. Improved internals
  100. Split up core library • Old: • wicket.jar
  101. Split up core library • Old: • wicket.jar • New: • wicket-requests.jar • wicket-util.jar • wicket-core.jar
  102. Maven users <dependency> <groupId>org.apache.wicket</groupId> <artifactId>wicket-core</artifactId> <version>1.5-RC1</version> </dependency>
  103. Simpler request cycle
  104. Wicket < 1.5 • Decoding request and handling in state machine • Debugging ‘interesting’ • Designed for flexibility • Served its purpose—took on 4 years of engineering
  105. Wicket 1.5 • Request cycle processing completely rewritten • Rendering code has been improved and simplified • URL rendering simplified: now in one place
  106. Wicket < 1.5 • Custom request cycle: subclass WebRequestCycle • Problematic with add-ons: • HibernateRequestCycle • SecureRequestCycle • ActivityRequestCycle
  107. New: RequestCycleListener public interface IRequestCycleListener { void onBeginRequest(RequestCycle cycle); void onEndRequest(RequestCycle cycle); void onDetach(RequestCycle cycle); IRequestHandler onException(RequestCycle cycle, Exception ex); }
  108. RequestCycleListener public class SomeWebApplication extends WebApplication { @Override protected void init() { } @Override public Class<? extends Page> getHomePage() { return SomePage.class; } }
  109. RequestCycleListener public class SomeWebApplication extends WebApplication { @Override protected void init() { addRequestCycleListener(new IRequestCycleListener() { public void onBeginRequest() { // do something at the beginning of the request } public void onEndRequest() { // do something at the end of the request } public void onException(Exception ex) { // do something here when there's an exception } }); } @Override public Class<? extends Page> getHomePage() { return SomePage.class; } }
  110. Switching to HTTPS
  111. Switching to HTTPS public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); } }
  112. Switching to HTTPS @RequireHttps public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); } }
  113. Switching to HTTPS @RequireHttps public SecurePage extends WebPage { ... } public MyApplications extends WebApplication { @Override public void init() { super.init(); setRootRequestMapper( new HttpsMapper(getRootRequestMapper(), new HttpsConfig()); } }
  114. Component event bus
  115. Component event bus • IEventSource: objects that send events <T> void send(IEventSink sink, Broadcast broadcast, T payload); • IEventSink: objects that receive events void onEvent(IEvent<?> event); • Participants: Components, RequestCycle, Session and Application
  116. Event bus example Ajax link counter
  117. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new Link<Void>("link") { @Override public void onClick() { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks"))); } }
  118. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new Link<Void>("link") { @Override public void onClick() { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  119. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; } }); add(new Label("clicks", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  120. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  121. This link has been clicked 123 times public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  122. Pre-event bus • Link needs to know the updatable components • Makes code brittle, hard to maintain • Better: • Let the label refresh itself with each Ajax request
  123. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; target.add(getPage().get("count")); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  124. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; send(getPage(), Broadcast.BREADTH, target); } }); add(new Label("count", new PropertyModel<Integer>(this, "clicks")) .setOutputMarkupId(true)); } }
  125. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { @Override public void onClick(AjaxRequestTarget target) { count++; send(getPage(), Broadcast.BREADTH, target); } }); add(new CountLabel("count", new PropertyModel<Integer>(this, } }
  126. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { } }
  127. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); } } }
  128. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } } }
  129. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } @Override public void onEvent(IEvent<?> event) { super.onEvent(event); } } }
  130. public class ClickCountPage extends WebPage { private int clicks = 0; public ClickCount() { add(new AjaxLink<Void>("link") { ... }); add(new CountLabel("count", new PropertyModel<Integer>(this, } public class CountLabel extends Label { public CountLabel(String id, IModel<Integer> model) { super(id, model); setOutputMarkupId(true); } @Override public void onEvent(IEvent<?> event) { super.onEvent(event); if (event.getPayload() instanceof AjaxRequestTarget) { AjaxRequestTarget target = (AjaxRequestTarget) event.getPayload(); target.add(this); } } } }
  131. Post-event bus • A bit more code • Updates are now completely decoupled • Make the payload type safe and meaningful: no AjaxRequestTarget, but CountEvent • AJAX requests trigger a default event with an AjaxRequestTarget as payload
  132. And much, much more: http://cwiki.apache.org/WICKET/ migration-to-wicket15.html
  133. Thank you! Questions? Ask!

Notizen

  • \n
  • \n
  • \n
  • refresher course voor Wicket\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • quickstart, leg before wicket, projecten en boeken\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • - debug mode voor quick turnaround\n - jrebel\n - markup reloading\n - markup/js/css in package structuur\n - development mode: excellente excepties, andere tools voor ontwikkelaars\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • - wicket tester\n - jdave\n - page test (kent tong?)\n - cucumber wicket\n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • ×