Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tapestry Wiki" for 
change notification.

The following page has been changed by michaelcourcy:
http://wiki.apache.org/tapestry/Tapestry5How_to_make_a_basic_crud

------------------------------------------------------------------------------
  
  === Introduction ===
  
- This tutorials aims to present you how easy and elegant could be the 
conception of a Crud cycle in tapestry 5.
+ This tutorials aims to present how to make a simple Crud cycle in tapestry 5.
+ 
+ Before reading this tutorial, you should read the 
[http://tapestry.apache.org/tapestry5/tutorial1/ Howard Lewis Ship's tutorials] 
as we're going to reuse without re-explaining them all the concepts they 
introduce.
  
  In order to stay focused on the question of CRUD we're not going to deal with 
a database or wondering about transactions. If you want to work on a tutorial 
that deals with this question in great details you should 
[http://wiki.apache.org/tapestry/Tapstry5First_project_with_Tapestry5,_Spring_and_Hibernate
 read this one carrefully].
  
@@ -205, +207 @@

  
  === Inject the service ===
  
- Injecting a service in Tapestry is really easy, just add a bind method to 
your AppModule.java 
+ Injecting a service in Tapestry is really easy, just add a bind method to 
your AppModule.java  
  
  in org.apache.tapestry.tutorial.basiccrud.services.AppModule.java add this 
method
  {{{
@@ -221, +223 @@

  
  Now the BeanManager is available in any tapestry component through the 
@Inject annotation.
  
+ More explaination on 
[http://tapestry.apache.org/tapestry5/tapestry-ioc/module.html binding service 
interfaces to service implementations]
+ 
  === Display a list of beans in the Start page ===
  
- Change Start.java to display a list of beans and handle some CRUD actions
+ Change Start.java to display a list of beans and handle the delete action.
  {{{
  
  package org.apache.tapestry.tutorial.basiccrud.pages;
+ 
  
  import java.util.List;
  
@@ -243, +248 @@

        @Inject 
        private BeanManager beanManager;
        
-       @InjectPage
-       private Save save;
-       
-       private boolean emptyList;
-       
        private MyBean myBean;
        
        public MyBean getMyBean() {
@@ -264, +264 @@

  
        public boolean isEmptyList() {
                return beanManager.getMyBeans().isEmpty();
-       }
+       }       
+               
-       
-       public Object onActionFromCreate(){
-               MyBean myBean = new MyBean();
-               myBean.setName("Choose a name");                
-               save.setMyBean(myBean);
-               return save;
-       }
-       
-       public Object onActionFromEdit(Long id){
-               save.setMyBean(beanManager.getMyBean(id));
-               return save;
-       }
        
        public void onActionFromDelete(Long id){
                beanManager.delete(id);
-       }
+       }       
        
-       
  }
  
  }}}
  
- Notice that: 
  
   * We inject the beanManager service through the @Inject annotation
-  * onActionFromCreate that initialize a new bean, pass it to the save page 
and return the Save page, the Save page is going to hold the form.
-  * onActionFromEdit, that retreives a bean with its id, pass it to the save 
page and return the Save page.
   * onActionFromDelete that just remove the bean from the list but return 
nothing, because we stay on the same page. The list is only refreshed.
+  * onActionFromDelete will be called each time the component actionLink 
having for id "delete" will be clicked.
  
   Change Start.html in the WEB-INF directory
   {{{
@@ -304, +290 @@

      <body>
          <h1>basicCrud of MyBean</h1>
                
-               <p><t:actionlink t:id="create">Create a new 
MyBean</t:actionlink></p>
+               <p><t:pagelink t:page="Save" context="0">Create a new 
MyBean</t:pagelink></p>
                
                <t:if test="emptyList">
                
@@ -313, +299 @@

                        <t:parameter name="else">
                                <t:loop source="myBeans" value="myBean">
                                  ${myBean.name}
-                             <t:actionlink t:id="edit" 
context="myBean.id">Edit</t:actionlink>
+                             <t:pagelink t:page="Save" 
context="myBean.id">Edit</t:pagelink>
                              <t:actionlink t:id="delete" 
context="myBean.id">Delete</t:actionlink>
                              <br/>
                            </t:loop>   
@@ -328, +314 @@

   
   }}}
   
+ 
+   * There's two 
[http://tapestry.apache.org/tapestry5/tapestry-core/component-parameters.html#orgapachetapestrycorelibcomponentsactionlink
 pageLinks]
+   * One 
[http://tapestry.apache.org/tapestry5/tapestry-core/component-parameters.html#orgapachetapestrycorelibcomponentsactionlink
 actionLink]
+   * Both initialize their context using the id of the bean
-  For each id 
-  {{{
-  
-  <t:actionlink t:id="edit" context="myBean.id">Edit</t:actionlink>
-  
-  }}}
-  
-  We made the corresponding handler
-  
-  {{{
-  
-  public Object onActionFromEdit(Long id){
-               save.setMyBean(beanManager.getMyBean(id));
-               return save;
- }
-  
-  }}}
   
   
  === Edit or create a bean ===
@@ -360, +333 @@

  import org.apache.tapestry.tutorial.basiccrud.model.MyBean;
  import org.apache.tapestry.tutorial.basiccrud.services.manager.BeanManager;
  
- public class Save {
+ public class Save {   
        
-       @Persist        
        private MyBean myBean;
+       
+       @Persist
+       Long id;
        
        @Inject
        private BeanManager beanManager;
@@ -371, +346 @@

        @InjectPage
        private Start start;
        
+       public void onActivate(Long id){                
+               if(id.equals(0L)){
+                       myBean = new MyBean();                  
+               }else{
+                       myBean = beanManager.getMyBean(id);
-               
+               }
+               this.id = id;
+       }
+       
+               
+       public Long  onPassivate(){
+               return id;
+       }
+       
+       public Object onSubmit(){
+               beanManager.save(myBean);
+               return start;
+       }       
+       
        public MyBean getMyBean() {
                return myBean;
        }
  
        public void setMyBean(MyBean myBean) {
                this.myBean = myBean;
-       }       
+       }
-       
-               
-       public Object onSubmit(){               
-               beanManager.save(myBean);
-               return start;
-       }
  
  }
   
  }}}
  
- Which is quite self explainatory.
+  * onActivate and onPassivate are part of the 
[http://tapestry.apache.org/tapestry5/tapestry-core/guide/pagenav.html page 
navigation]
+  * onActivate will use the context to initialize values in the Save page 
component.
+  * onPassivate is used when no context is explicitly provided in a pageLink 
for the Save page
+  * When we hit Save page the first time using a pageLink : 
+    1. onActivate is called first, myBean is initialized.
+    2. onPassivate is called, tapestry use the returned value to persist it
+  * When we filled the form and submit it 
+    1. onActivate is called again but this time tapestry provide the argument 
obtained from onPassivate before.
+    2. onSubmit is called
+    
+       
+    
  
  And Save.html 
  {{{
@@ -401, +399 @@

  </head>
  <body>
  
-    
-     ${myBean.name}<br/>
-     ${myBean.id}<br/>
-    
-       <t:form>
+       <t:form>
        <t:errors/>
        <t:label t:for="name"/> 
          <input t:type="textfield" t:id="name" t:value="myBean.name"/><br/>
@@ -414, +408 @@

      </t:form>
  
  
- 
  </body>
  </html>
  
@@ -433, +426 @@

  
  === Conclusion ===
  
- As you can see building a CRUD cycle in Tapestry 5 is really easy. Instead of 
the other framework we didn't use a code generator or other magic un/ex-plicit 
rules, things are clear from the start and you know exactly what you do. 
+ I made this tutorial because I needed one and thought that I probably was not 
the only one. Many thanks to the users mailing list that point on weakness and 
help me to make it better.
  
- Even in this example tutorial we where able to separate the service layer 
from the mvc layer without writing a single line of xml.
- 

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to