t's pretty simple actually. I have a menu that calls my page with a
commandLink. I use tiles, so my menu is the same on every page and I
only have to manage it in one place. I also setup my directory
structures so that they present logical groupings of pages. For
example all of my admin pages exist beneath the
"http://foo.com/myapp/pages/admin/";. This allows me to setup a
navigation rule that is a catch-all for any of the init items that my
menus call.

       <navigation-rule>
               <from-view-id>/pages/admin/*</from-view-id>
               <navigation-case>
                       <from-action>#{categoryAdmin.init}</from-action>
                       <from-outcome>init</from-outcome>
                       <to-view-id>/pages/admin/category.jsp</to-view-id>
               </navigation-case>
       </navigation-rule>

Any specific mappings i have i can setup before my catch-all rule:

       <navigation-rule>
               <from-view-id>/pages/admin/category.jsp</from-view-id>
               <navigation-case>
                       <from-action>#{categoryAdmin.child}</from-action>
                       <from-outcome>child</from-outcome>
                       <to-view-id>/pages/admin/category.jsp</to-view-id>
               </navigation-case>
       </navigation-rule>

       <navigation-rule>
               <from-view-id>/pages/admin/*</from-view-id>
               <navigation-case>
                       <from-action>#{categoryAdmin.init}</from-action>
                       <from-outcome>init</from-outcome>
                       <to-view-id>/pages/admin/category.jsp</to-view-id>
               </navigation-case>
       </navigation-rule>

Now that i am using the init method i simply populate the default
values in my UIData (or whatever UIComponent i want) in the init
method. Then JSF does the magic of maintaining those values. Keeps me
from hitting my databaes and it keeps my setters and getters perfectly
clean.

public class CategoryAdminPresentation {

 // business logic
 private CatalogService catalogService;

 private Category category;

 private UIData categoryTable;

 /**
  * no arg contructor
  */
 public CategoryAdminPresentation() {
   this.catalogService =
(CatalogService)ServiceFactory.getInstance().getService(CatalogService.class);
 }

 public String init() {

   categoryTable = new UIData();
   categoryTable.setValue(catalogService.getChildCategories(category));

   return "init";
 }

 public String child() {

   Category category = (Category)categoryTable.getRowData();

   // create parent category template
   Category parentCategory = new Category();
   parentCategory.setParentCategoryId(category.getCategoryId());

   categoryTable.setValue(catalogService.getChildCategories(parentCategory));

   return "child";
 }

 /**
  * @return Returns the categoryTable.
  */
 public UIData getCategoryTable() {
   return categoryTable;
 }
 /**
  * @param categoryTable The categoryTable to set.
  */
 public void setCategoryTable(UIData categoryTable) {
   this.categoryTable = categoryTable;
 }

 /**
  * @return Returns the category.
  */
 public Category getCategory() {
   return category;
 }
 /**
  * @param category The category to set.
  */
 public void setCategory(Category category) {
   this.category = category;
 }
}

Brandon

On 4/14/05, Neal Haggard <[EMAIL PROTECTED]> wrote:
> Out of curiosity, you say you are goint to make sure all access to this page 
> calls your init message, how are you going to do that?
> 
> -----Original Message-----
> From: Brandon Goodin [mailto:[EMAIL PROTECTED]
> Sent: Thursday, April 14, 2005 2:22 AM
> To: MyFaces Discussion
> Subject: Re: dataTable and commandButton question
> 
> okay i solved my own problem.
> 
> I didn't realize that JSF magically retains my state even when my managed 
> bean is in request mode. Thanks JSF/MyFaces!
> 
> All i need to do is intialize my UIData value with a list from the database 
> the first time i access it.After that i update my UIData value via the action 
> that i call. Everytime UIData value is attempted to be set it will see that 
> it is not null and leave it alone. So, i only hit my db once for the initial 
> list and then after that only intentionally. This allows me to be sure that 
> the index object will be what i am expecting it to be.
> 
> I think i am going to make this even easier by making sure that all access to 
> this page calls the #{categoryAdmin.init} action first. Then i can even do 
> away with the faux init wrapper.
> 
> ...
>   /**
>    * @return Returns the categoryTable.
>    */
>   public UIData getCategoryTable() {
>     return initCategoryTable(categoryTable);
>   }
>   /**
>    * @param categoryTable The categoryTable to set.
>    */
>   public void setCategoryTable(UIData categoryTable) {
>     this.categoryTable = initCategoryTable(categoryTable);
>   }
> 
>   private UIData initCategoryTable(UIData categoryTable) {
>     if(categoryTable.getValue() == null) {
>       categoryTable.setValue(catalogService.getChildCategories(category));
>     }
>     return categoryTable;
>   }
> ...
> 
> On 4/13/05, Brandon Goodin <[EMAIL PROTECTED]> wrote:
> > wow, after looking at all the proposed solutions i wound up coming
> > back to what i was doing before. Which is exactly what Srikanth
> > recommended. Is there a reason why the rest of you chose such obscure
> > routes to the getRowData?
> >
> > Also it seems that no matter what i do the UIData property that my
> > dataTable is bound too on my backing bean get's called twice. Once
> > before the action is called and once after the action method is
> > called. When i select an item with the commandLink I am only
> > interested in the id of that element. It seems that i HAVE to load the
> > whole list back in just to get the id from the selected index of the
> > list. I prefer not to keep lists in my session scope and so my managed
> > bean is request scope and i load lists only as i need them. But, the
> > auto loading that is performed by JSF does not make this easy. Is
> > there a way around this?
> >
> > I currently have an init boolean for my UIData so that the list will
> > only load once from my service layer. I would prefer that the List not
> > have to be loaded when i select the commandLink. Like i said i'm only
> > interested in the id. Also, the odd thing about grabbing the selected
> > object using the getRowData (which looks up the index) is that the
> > list i grab from my service layer may have been updated. So, then the
> > index would return the wrong object. Does everyone simply load up all
> > their lists into their managedbeans and store them in session scope?
> >
> > It doesn't seem that developing something as simple as this should be
> > so difficult.
> >
> > Following is my code.
> >
> > ...
> >
> >   private CatalogService catalogService = null;
> >
> >   private Category category = new Category();
> >
> >   private UIData  categoryTable = new UIData();
> >   private boolean categoryTableInit = false;
> >
> >   /**
> >    * no arg contructor
> >    */
> >   public CategoryAdminPresentation() {
> >     this.catalogService =
> > (CatalogService)ServiceFactory.getInstance().getService(CatalogService.class);
> >   }
> >
> >   public String child() {
> >
> >     Category category = (Category)categoryTable.getRowData();
> >
> >     // create parent category template
> >     Category parentCategory = new Category();
> >     parentCategory.setParentCategoryId(category.getCategoryId());
> >
> >
> > categoryTable.setValue(catalogService.getChildCategories(parentCategor
> > y));
> >
> >     return "child";
> >   }
> >
> >   /**
> >    * @return Returns the categoryTable.
> >    */
> >   public UIData getCategoryTable() {
> >     return initCategoryTable(categoryTable);
> >   }
> >   /**
> >    * @param categoryTable The categoryTable to set.
> >    */
> >   public void setCategoryTable(UIData categoryTable) {
> >     this.categoryTable = initCategoryTable(categoryTable);
> >   }
> >
> >   private UIData initCategoryTable(UIData categoryTable) {
> >
> >     if(categoryTableInit==false) {
> >       categoryTable.setValue(catalogService.getChildCategories(category));
> >       categoryTableInit = true;
> >     }
> >
> >     return categoryTable;
> >
> >   }
> >
> >   /**
> >    * @return Returns the category.
> >    */
> >   public Category getCategory() {
> >     return category;
> >   }
> >   /**
> >    * @param category The category to set.
> >    */
> >   public void setCategory(Category category) {
> >     this.category = category;
> >   }
> >
> > ...
> >
> > Thanks,
> > Brandon
> >
> > On 4/13/05, Brandon Goodin <[EMAIL PROTECTED]> wrote:
> > > This rowData works okay, if you are using session... but there are
> > > problems with this. Most of the time you want to query based on the
> > > ID of your object. Not the index of the object location. If you
> > > database changes behind the scenes and you query a list from the
> > > database, the index may produce a different object. The important
> > > thing to me is to get the ID for the query. I don't like to keep
> > > lists of objects in session. That's weighty and pointless.  I
> > > appreciate the previous contributions. I'm going to try them out later 
> > > this evening.
> > >
> > > Please correct me if i'm wrong.
> > >
> > > Thanks,
> > > Brandon
> > >
> > > On 4/13/05, Srikanth Madarapu <[EMAIL PROTECTED]> wrote:
> > > > In your backing bean, you must have access to the model (of your table 
> > > > ), just call   yourModel.getRowData() to get the current row's data or 
> > > > yourModel.getRowIndex to the currenty row's index.
> > > >
> > > > -----Original Message-----
> > > > From: Ray Clark [mailto:[EMAIL PROTECTED]
> > > > Sent: Wednesday, April 06, 2005 10:46 PM
> > > > To: [email protected]
> > > > Subject: dataTable and commandButton question
> > > >
> > > > I'm sure this must have been asked before but I can't find it in
> > > > the archives.  So please forgive me if it has been asked before.
> > > >
> > > > I have a dataTable with a commandButton rendered on each row.
> > > > When the commandButton is pressed I need it's managed bean method
> > > > to know which row the button was pressed for.  So how can the
> > > > method know which row to process?
> > > >
> > > > Thanks,
> > > > Ray
> > > >
> > > > __________________________________
> > > > Do you Yahoo!?
> > > > Take Yahoo! Mail with you! Get it on your mobile phone.
> > > > http://mobile.yahoo.com/maildemo
> > > >
> > >
> >
>

Reply via email to