[ 
https://issues.apache.org/jira/browse/MYFACES-2616?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12847567#action_12847567
 ] 

Leonardo Uribe commented on MYFACES-2616:
-----------------------------------------

Attached patch with fix for transient properties as suggested by Alexander 
Smirnov. The idea is create an interface that allows to save/restore transient 
properties like UIForm.submitted, to be saved per row. In that way, the state 
could be fully restored and saved for each component.

> Fix UIData state saving model (spec issue 153)
> ----------------------------------------------
>
>                 Key: MYFACES-2616
>                 URL: https://issues.apache.org/jira/browse/MYFACES-2616
>             Project: MyFaces Core
>          Issue Type: Task
>          Components: JSR-314
>    Affects Versions: 2.0.0-beta-2
>            Reporter: Leonardo Uribe
>            Assignee: Leonardo Uribe
>         Attachments: fixUIDataPSS-6.patch, fixUIDataPSS-7.patch
>
>
> In short, this topic is an attempt to add full state to components inside 
> UIData. I'll do a brief resume, so people can understand this one easily.
> UIData uses the same component instances to render multiple rows. Suppose 
> this example:
> <h:dataTable id="cities" var="city" value="#{country.cities}">
>     <h:column>
>         <h:outputText value="#{city}"  />
>     </h:column>
> </h:dataTable>
> In the component tree it is created this hierarchy:
> HtmlDatatable
>   UIColumn
>     HtmlOutputText
>    
> If we have 10 cities, the same component is used over and over to render all 
> 10 cities. The reason to do that in this way is keep state as small as 
> possible.
> Now let's suppose something like this:
> <h:dataTable id="cities" var="city" value="#{country.cities}">
>     <h:column>
>         <h:inputText value="#{city}"  />
>     </h:column>
> </h:dataTable>
> It was changed the output component for an input one. If this table is in a 
> form and the values are submitted, the same component is used to apply 
> request values, validate and apply them to the model (update process). To 
> make this possible, UIData class has some code to preserve this values 
> between phases (using EditableValueHolder interface), so when each phase is 
> processed, all rows are traversed and you get the expected behavior.
> Now suppose something more complex: We have a code that use invokeOnComponent 
> to change the style of my inputText. In theory, only one row should change. 
> But in fact, all rows are rendered with the same color. Why? because we use 
> the same component to render all rows, and we don't preserve the children 
> component state between rows.
> There is a lot of issues, questions, and side effects related to this issue, 
> but just to put some of them here:
> TOMAHAWK-1062 InputTextArea doesn't work properly inside facet DetailStamp
> TOMAHAWK-96 Data table Scroller not working the dataTable which was actually 
> contained in other DataTable
> https://javaserverfaces-spec-public.dev.java.net/issues/show_bug.cgi?id=153 
> Problems with UIData state saving
> Also, it is well know that one reason why people uses c:forEach in facelets, 
> is because this one create "full" components per each row. It is very easy to 
> find articles on internet.
> Now, with jsf 2.0 we have partial state saving, so we have a chance to fix 
> this one once and for all. I tried fix this one per months (maybe years!), 
> but talking with Martin Marinschek on JSFDays, some ideas came out and 
> finally it was found a possibility to fix this one using the existing api and 
> with little changes on the spec.
> The proposal is this:
> 1. Do not call UIComponent.markInitialState() on ComponentTagHandlerDelegate, 
> as ComponentHandler javadoc says, instead call it after PostAddToViewEvent 
> are published on vdl.buildView(). We need to call it from root to nodes, so 
> the parent component is marked first. I know the place where this call comes 
> is from trinidad tag handler, but this call needs to be fixed in a more 
> predictable way.
> 2. Use an attribute on facesContext to identify when the VDL is marking the 
> initial state (in myfaces there is already an attribute called 
> "org.apache.myfaces.MARK_INITIAL_STATE"). This is necessary to indicate 
> UIData instances that it is time to save the full state of all component 
> children,
> 3. Allow UIData to hold a map where the key are client ids and the value are 
> the deltas of all components per row. This map should be saved and restored.
> 4. Change UIData.setRowIndex() to restore and save the component state.
> I'll attach a patch on this issue with the algorithm proposed (because it is 
> based on myfaces codebase). It was tested and it works. But note it is 
> necessary to fix the javadoc for UIData.markInitialState(), ComponentHandler 
> and maybe vdl.buildView(), so the intention is propose this change for jsf 
> 2.0 rev A. Note this works only with PSS enabled because without it we don't 
> have a place to notify UIData instances that it is necessary to get the full 
> state. Also, note this patch preserve backward compatibility, because the old 
> way to store/save is applied after the full state is restored.
> Really, I have the strong temptation to apply some similar code on myfaces 
> UIRepeat component (because this class is private), but I prefer first ask to 
> EG.

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply via email to