1 2 Previous Next 27 Replies Latest reply on Jul 1, 2010 1:38 PM by dan.j.allen Go to original post
      • 15. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
        ilya_shaikovsky

        Last question on auto-updates.

         

        On encoding we are search for registered auto-updatable zones. (marked with ajaxRendered) and added them to render set.

        In 3.3.x we also looked for them in all iteration components and this caused model of every table/repeat/list to be called. That caused https://jira.jboss.org/jira/browse/RF-3341 to appear.

         

        In 4.x we do not want to use this approach. But for common usecase - editable table the user might want to have messages in the rows and do not care of updates. So messages, or outputPanels presence in context of the row will be still checked. (B.t.w. OPEN question maybe extend to whole table?). And even this autoupdate could be turned of by setting limittolist at controls. And if the user need to update some such elements in the other table or performing the request from controls outside the table - he still need to define the components in render properly.

        • 16. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
          ilya_shaikovsky

          One more addition. Seems life could not be so easy as we imagined from the beginning

           

          The problem is:

           

          render="tableId:#{someCollection}":cellId"

           

          works fine only until complex objects used as rowKey's. Then we do not know how to produce list of ids from string produced by this collection toString where collection items are some custom objects converted using custom rowKeyConverter.

           

          We can't parse #{someCollection} in a custom way because this requires custom expression factory implementation and knowledge which expressions should be processed by our custom resolver. This looks like too complex way.

           

          So the task is to process someCollection invoking converter which already defined by developer and create list of actual id's Strings in the format we need.

           

          And most convenient way we see for now is to modify which we expect from customer to:

           

          2) render="tableId:#{rich:rowKeysFromList(someCollection, 'tableId')}:cellId"  where we invoked our utility function rowKeysFromList which will process the keys with table converter and create String which we know how to handle. And in order not to duplicate tableId definitions we propose to have next final definition:

           

          3) render="#{rich:rowKeys(someCollection, 'tableId')}:cellId" - will generate the same result as we planned for 1)

           

          However if the user not redefined rowKey's with the custom he still could use 1) notation - we will handle it by default as collection of rowIndexes -> toString().

          • 17. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
            jbalunas
            ok good - that is what I thought but wanted to make sure.
            • 18. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
              jbalunas

              Define "complex object".  If a user uses a list of Integers - will that work?  Or a list of Strings of Integers?

              • 19. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                nbelaevski

                Here complex object stands for the object for which rowKeyConverter.getAsString(key) != key.toString(). Example of this can be complex entity id, consisting of several fields, without overriden toString() method. Examples of non-complex objects are numbers and strings.

                 

                To clarify, I'll add more on the problem that conversion function is going to solve. By default, mixed EL-expressions are evaluated into strings, when their value is requested. For this expression: "table:#{rowKeys}:cell", we'll get the following evaluation rules:

                String toString(Object o) {
                     return o != null ? o.toString() : "";
                }
                
                
                "table:" + toString(rowKeys) + ":cell"
                

                So when rowKeys is a collection of ComplexId types without overriden toString() method, expression will be evaluated as following:

                "table:" + "[" /* opening bracket from Collection#toString() */ + 
                          "ComplexId@xyxyxyxy, " /* first item */ +
                          "ComplexId@xyxyxyxy, " /* second item */ +
                          ...
                     "]" + /* closing bracket from Collection#toString() */
                

                and "ComplexId@xyxyxyxy" is not the thing that can be converted back to the type of row key by using converter.

                 

                So, with conversion function, the expression is evaluated as follows:

                "table:" + "[" /* opening bracket from Collection#toString() */ + 
                          rowKeyConverter.getAsString(complexId1), /* first item */ +
                          rowKeyConverter.getAsString(complexId2) /* second item */ +
                          ...
                     "]" + /* closing bracket from Collection#toString() */
                

                and can be converted back into instances of ComplexId using rowKeyConverter.

                • 20. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                  jbalunas
                  This all makes much more sense to me.  Your explanation is clear this way.
                  • 21. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                    ilya_shaikovsky

                    One more point related to tables and AjaxOutput components inside. (output panels with ajaxRendered=true and messages and so on..)

                     

                    This how we would decide if the table would be marked to check ajaxRendered inside or not.

                    Now we want to solve https://jira.jboss.org/jira/browse/RF-3341 problem. Thanks to JSF 2 no we have special system events(risen when component created) which allows us to handle outputPanels(or based components like messages) usage in the table and mark that concrete table for looking for ajaxRendered content inside. That allows us to tell to the developers that tables still will be checked on updates needed inside but not always as it was for 3.3.x - but just if components which implements AjaxOutput present inside.

                    ajaxRendered could also be defined with EL and even pointed to iteration var attribute. So we do not want to check the actual value of ajaxRendered but make decision on just if the AjaxOutput present in table or no.

                     

                    So if AjaxOutput present in some tables on the page - ajaxRendered elements rendered for all rows of the tables. And it could be only limited by using limitRenderToList=true at ajax command control.

                     

                     

                    Nick and Alex has the discussion about that thread and auto-updates and one of the proposal was to keep AjaxKeys functionality at least partially and in the same time use new one described there also. To be honest I vote against such decision because believe the users should have single place where rows for updates should be defined.

                     

                    Thoughts?

                    • 22. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                      jbalunas

                      Is there a different way to support AjaxRendered elements without ajax keys?  Can the support be made to work with new design above?

                       

                      I am not completely understanding the point about JSF 2 events - can we use these or not?

                      • 23. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                        nbelaevski

                        To be more clear with partial updates in 4.x, I'll introduce some points about the same updates in 3.x.

                         

                        First of all, base example:

                                  <a4j:repeat value="#{forum5Bean.data}" var="item">
                                       <h:panelGrid>
                                            <a4j:commandLink value="#{item}" id="link" reRender="time" />
                             
                                            <a4j:outputPanel id="time">
                                                 Explicitly updated: #{forum5Bean.currentTime}
                                            </a4j:outputPanel>
                                            <a4j:outputPanel ajaxRendered="true">
                                                 Implicitly updated: #{forum5Bean.currentTime}
                                            </a4j:outputPanel>
                                       </h:panelGrid>
                                  </a4j:repeat>
                        
                        

                        It contains link in iteration component (IC from now and below) that fires AJAX request and explicitly update "time" component.

                        This base example doesn't define ajaxKeys and uses defaults. In 3.x this means that:

                        1. Clicked (or activated in another way) row of IC is added to internal set of ajaxKeys
                        2. When control is passed to AJAX IC it iterates via rows limited to ajaxKeys or all rows if no ajaxKeys are set. During these iterations, explicit and implicit updates are done.

                         

                        1st point causes interesting behavior - for the current IC updates are limited to the current active row, bot for other ICs all rows are updated.

                        2nd point has https://jira.jboss.org/jira/browse/RF-3341 as side effect.

                         

                        Explicit specification of AJAX keys for all tables in view is not an easy thing - there should be some kind of controller changing state for all ICs' keys.

                         

                        One more thing to consider for 3.x: AJAX updates inside partial components are limited to RF components, so inside h:dataTable implicit updates don't work.

                         

                        What can be changed in 4.x:

                        1. non-RF components can be partially updated too. JSF 2 introduces new way of tree traversal that provides full information about "virtual components" represented by components nested in ICs.
                        2. JSF 2 system events can be exploited to track implicitly rendered components. This helps with RF-3341, but requires to split a4j:outputPanel: http://community.jboss.org/message/531048#531048 (BTW by this split we can finally make ajaxRendered="true" by default).
                        3. "ajaxKeys" vs client IDs

                         

                        The main question: how to control updates for implicitly rendered components?

                         

                        Proposals:

                         

                        1. Leaving "ajaxKeys" as is and not using IDs
                        2. Combine "ajaxKeys" (for implicitly-updated components) with IDs
                        3. Limiting implicit updates inside IC to the current active row, no implicit updates for external ICs & their children (NB: user can specify implicit components explicitly)
                        4. Implicit updates without limitations for all rows + explicit updates according to IDs.

                         

                        For all variants we solve RF-3341 by checking if IC contains explicit/implicit updates without model initialization.

                         

                        Pros/cons for the proposals above:

                         

                        1) is proven scheme, but not very suitable.

                        2) brings lot of questions about the degree of combination.

                        3) causes loss of updates expected by the user.

                        4) seems to be the optimum:

                        • Doesn't need/use ajaxKeys
                        • Behavior is fully compatible with non-RF components. Implicitly updated components are updated in all rows of IC by default without limitations.
                        • Developer can limit updates using "limitRender" boolean attribute
                          • New for 4.x is that developer can do update for "@row" effectively causing updates both explicit/implicit components in the current row.

                         

                        Thoughts/opinions?

                        • 24. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                          alexsmirnov

                          My expectations as the application developer are closest to the case 4), so it would be better solution.

                          What about "execute" attribute/phase, do they have to follow the same pattern or framework should process all rows ?

                          • 25. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                            nbelaevski

                            alexsmirnov wrote:

                             

                            My expectations as the application developer are closest to the case 4), so it would be better solution.

                             

                            I also think 4) is the best of the options

                             

                            alexsmirnov wrote:

                             

                            What about "execute" attribute/phase, do they have to follow the same pattern or framework should process all rows ?

                            We discussed addition of "executeKeys" and it seems that we do not need fine-grained control for what's executed. Keywords like "@this", "@row" plus explicit component IDs should be enough.

                            • 26. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                              jbalunas

                              I agree that the 4th options seems the most likely to be expected, lets go with that approach.

                               

                              As for executeKeys - I agree it seems to me that the available values would be enough.  If something more is needed we can add it after some feedback.

                              • 27. Re: RichFaces 4.0: Controlling AJAX updates for iteration co
                                dan.j.allen

                                Related (I didn't see this post first)

                                 

                                Suggestion for component id addressing

                                1 2 Previous Next