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
> > > >
> > >
> >
>