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]
