Okay, first thank you. 2nd, REALLY sorry for being a complete JERK and
making unbacked accusations against your code once again (Man if I
keep this up, I'm going to have to ban myself from these list groups
to stop myself from looking like a complete idiot and ticking everyone
else off).
Okay, I cached the view ID and returned null for the UIData if the
view was different just to test, and it worked.
Now that I have completely been humbled, I may as well plead for advice.
What I need to do:
I have a table with tens of thousands of records. Obviously not very
nice for the user to scroll through to find a record. So, I have a
find button. On that find, I select the first object found after the
current selection (with wrapping). I want to make sure that row is
highlighted and visible to the user in the data table.
What I have done (incorrectly):
1) Have a data table with a value pointing to my backing bean's
DataModel that handles filtering, sorting, etc.
2) have that data table bound to a UI data property
3) During the find actionListener method, programmatically, call
"setFirst(row)" on the UI data to make sure the row I want is visible.
I don't want to create the components in the backing bean or do
anything besides change the first row. I didn't use an EL expression
in the view, as I only wanted the first to be set during that action.
How can I do this better?
Thanks (and sorry again)
-Andrew
On 4/14/06, Adam Winer <[EMAIL PROTECTED]> wrote:
> Move the bean down to request scope, and let's
> see if the problems go away.
>
> -- Adam
>
>
> Andrew Robinson wrote:
> > Ah, I think you are on to something. Looks like maybe I screwed up (no
> > surprise there if it binding, since I almost never use it). I do have
> > a bean with:
> >
> > private UIData tableData;
> > public UIData getTableData() { return tableData; }
> > public void setTableData(UIData data) { tableData = data; }
> >
> > <t:dataTable binding="#{bean.tableData}"
> >
> > I did this as I need to programattically change which rows are
> > currently shown by the data scroller. I assumed (possibly very
> > incorrectly) that "setTableData" would be called for each new page
> > with the new data component created by the view. The error IS from a
> > component inside of that UIData component that has no id assigned to
> > it.
> >
> > Crud, new I didn't know that much about component binding.
> >
> > -Andrew
> >
> > On 4/14/06, Adam Winer <[EMAIL PROTECTED]> wrote:
> >> ... and if so is the backing bean at session scope?
> >>
> >> -- Adam
> >>
> >>
> >> [EMAIL PROTECTED] wrote:
> >>> Are you binding it to a backing bean?
> >>>
> >>>> It is, but I am not on the same view, I am on a new view. The new view
> >>>> is getting a component from the old view. So:
> >>>> 1) view #1 is restored,
> >>>> 2) the navigation handler is fired from an action result
> >>>> 3) a new view is created
> >>>> 4) *somehow* a tomahawk outputText component is getting added to the
> >>>> new component tree from the old component tree from inside of a
> >>>> decorated template.
> >>>>
> >>>> I am still trying to find where *exactly* the old component is getting
> >>>> added to the new view. I'll let you know when and if I find it.
> >>>>
> >>>> -Andrew
> >>>>
> >>>> On 4/14/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> >>>>> Look at the UIViewRoot source for MyFaces and see if the
> >>>> saveState/restoreState methods actually save the unique id counter.
> >>>>>> Jacob, the view root is not handing out the same ID. I have verified
> >>>>>> this by stepping through the MyFaces SVN code. UI view root is only
> >>>>>> handing out ID 81 once.
> >>>>>>
> >>>>>> The "DefaultFacelet.java" is rehydrating my decorated page and
> >>>>>> re-using components from the previous view. One of these is an output
> >>>>>> text component that got ID of 81 from the *LAST* view. When the new
> >>>>>> view includes the same facelet (a ui:decorate tag), that same
> >>>>>> outputText component is getting included into the new view.
> >>>>>>
> >>>>>> Evidence:
> >>>>>> During
> >>>>> org.apache.myfaces.application.TreeStructureManager.internalRestoreTreeStructu
> >>>> r
> >>>>>> e(TreeStructureManager.java:112)
> >>>>>>
> >>>>>> Output text component with ID _id81 and memory location @1965de4 gets
> >>>>>> restored.
> >>>>>>
> >>>>>> Navigation handler creates a new view root as it should (I navigated
> >>>>>> to a new page). As shown here:
> >>>>>> 13:34:32,877 DEBUG [NavigationHandlerImpl] handleNavigation
> >>>>>> fromAction=#{dimHandler.goView} outcome=goview toViewId
> >>>>>> =/pages/Admin/Appsets/Dimension/dim_view.xhtml redirect=false
> >>>>>>
> >>>>>> The new view generates a new component tree:
> >>>>>> 13:34:33,346 INFO [STDOUT] --------------- NEW UNIQUE ID: 81 (this:
> >>>>>> [EMAIL PROTECTED])
> >>>>>> 13:34:33,347 INFO [STDOUT] ---------- OutputText. this:
> >>>>>> [EMAIL PROTECTED] Setting
> >>>>>> Id to = _id81. View ID: [EMAIL PROTECTED]
> >>>>>>
> >>>>>> However, facelets is reusing the component from the old View in the new
> >>>> tree:
> >>>>>> 13:35:09,793 INFO [STDOUT] ---------- OutputText. this:
> >>>>>> [EMAIL PROTECTED] Id =
> >>>>>> _id81
> >>>>>> 13:35:09,794 INFO [STDOUT] ---------- OutputText. this:
> >>>>>> [EMAIL PROTECTED] Client
> >>>>>> Id = zfpForm:_id79:_id81
> >>>>>>
> >>>>>> As you can see, this is the exact same component (1965de4) from the
> >>>>>> previous view. This component was not created by the new view.
> >>>>>>
> >>>>>> The stack trace points the finger at default facelet:
> >>>>>> ...
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>> com.sun.facelets.impl.DefaultFaceletContext$1.apply(DefaultFaceletContext.java
> >>>> :
> >>>>>> 253)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>> com.sun.facelets.impl.DefaultFaceletContext.includeDefinition(DefaultFaceletCo
> >>>> n
> >>>>>> text.java:263)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>>> com.sun.facelets.tag.ui.InsertHandler.apply(InsertHandler.java:63)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>> com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.jav
> >>>> a
> >>>>>> :47)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>>> com.sun.facelets.tag.jsf.ComponentHandler.apply(ComponentHandler.java:164)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>> com.sun.facelets.tag.CompositeFaceletHandler.apply(CompositeFaceletHandler.jav
> >>>> a
> >>>>>> :47)
> >>>>>> 13:34:33,350 INFO [STDOUT] at
> >>>>> com.sun.facelets.tag.ui.CompositionHandler.apply(CompositionHandler.java:119)
> >>>>>> 13:34:33,351 INFO [STDOUT] at
> >>>>>> com.sun.facelets.compiler.NamespaceHandler.apply(NamespaceHandler.java:49)
> >>>>>> ...
> >>>>>>
> >>>>>> I'm trying to get more specific than this (trying to get the debug
> >>>>>> working in my IDE), but this is what I have found so far. Sorry if I
> >>>>>> am wrong on this, but it sure looks this way after looking at MyFaces
> >>>>>> and Facelets code for a few hours.
> >>>>>>
> >>>>>> -Andrew
> >>>>>>
> >>>>>>
> >>>>>>
> >>>>>> On 4/14/06, [EMAIL PROTECTED] <[EMAIL PROTECTED]> wrote:
> >>>>>>> The problem is that the UIViewRoot in older versions of MyFaces
> >>>>>>> doesn't
> >>>>>> guarantee that the Id is unique across calls-- which breaks the
> >>>>>> contract
> >>>> of
> >>>>>> the method. Facelets doesn't need to change anything.
> >>>>>>> Facelets doesn't 'cache' anything. It creates the tree and the state
> >>>> saving
> >>>>>> method of the JSF implementation saves the component tree for
> >>>>>> processing
> >>>> on
> >>>>>> succeeding requests (less the unique id counter on the viewroot).
> >>>>>>> If the UIViewRoot is fixed, then it should NEVER hand out the same
> >>>>>>> ids--
> >>>> so
> >>>>>> in a sense, the problem you are seeing is created by MyFaces itself.
> >>>>>>>> Okay, I've been digging deep into MyFaces SVN and facelets 1.0.14
> >>>>>>>> source code to try to find the issue of duplicate IDs. It looks like
> >>>>>>>> it is a facelets bug after all.
> >>>>>>>>
> >>>>>>>> What I've been able to find out so far:
> >>>>>>>>
> >>>>>>>> MyFaces creates a view with a bunch of facelets tags (defines,
> >>>>>>>> includes, compositions, etc.). This creates several facelets objects
> >>>>>>>> that represent cached "views" for defines and etc.
> >>>>>>>>
> >>>>>>>> The particular problem seems to be happening with
> >>>>>>>> DecorateHandler.java
> >>>>>>>> and the classes it is using. (I haven't pinpointed the exact problem
> >>>>>>>> as I am having stability issues debugging JBoss in eclipse, so am
> >>>>>>>> hunting and pecking through source in VIM).
> >>>>>>>>
> >>>>>>>> Facelets is caching the decorated view. So, when I hit the first page
> >>>>>>>> it is fine. At that point, facelets is caching the components that
> >>>>>>>> made up the view for my decorated page.
> >>>>>>>>
> >>>>>>>> Then, after navigation, and a new view is created, facelets seems to
> >>>>>>>> be re-hydrating this cached copy of the decorated view for the new
> >>>>>>>> view. This cache copy of components contains components with
> >>>>>>>> auto-generated IDs.
> >>>>>>>>
> >>>>>>>> The MyFaces UIViewRoot knows nothing about these cached components
> >>>>>>>> and
> >>>>>>>> therefore does not check any components in the view for existence of
> >>>>>>>> auto-generated IDs. Therefore when facelets adds the cached version
> >>>>>>>> of
> >>>>>>>> the component to the tree, it is not reserving unique IDs.
> >>>>>>>>
> >>>>>>>> As a result, the first component that was cached in the decorated
> >>>>>>>> file
> >>>>>>>> with an auto-generated ID will clash with any components in the new
> >>>>>>>> view given that very same auto -generated ID.
> >>>>>>>>
> >>>>>>>> The fix? Well this is up to you Jacob I guess, unless MyFaces wants
> >>>>>>>> to
> >>>>>>>> help with this.
> >>>>>>>>
> >>>>>>>> 1) In facelets, (during the mark & sweep?), when a cached component
> >>>>>>>> hierarchy is being used, check all IDs in the component tree with
> >>>>>>>> naming matching the regular expression "^_id\d+" and assign a new ID.
> >>>>>>>>
> >>>>>>>> Example:
> >>>>>>>> if (regex.matcher(component.getId()).matches()))
> >>>>>>>> component.setId( /* get a new ID from the view */);
> >>>>>>>>
> >>>>>>>> 2) In UIViewRoot of MyFaces, when components are added to the tree,
> >>>>>>>> or
> >>>>>>>> when assigning a new ID, check the existing components in the tree to
> >>>>>>>> make sure the auto generated ID has not already been assigned to a
> >>>>>>>> component (don't assume UIViewRoot is the only source of "_id#" style
> >>>>>>>> IDs)
> >>>>>>>>
> >>>>>>>> 3) Something else.
> >>>>>>>>
> >>>>>>>> What do you think?
> >>>>>>>> -Andrew
> >>>>>>>>
> >>>>>>>> ---------------------------------------------------------------------
> >>>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>>>
> >>>>>>> ---------------------------------------------------------------------
> >>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>>
> >>>>>>>
> >>>>>> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>
> >>>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: [EMAIL PROTECTED]
> > For additional commands, e-mail: [EMAIL PROTECTED]
> >
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>