ICEfaces
  1. ICEfaces
  2. ICE-2297

Nested UIData components don't reflect their changed data models

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Major Major
    • Resolution: Invalid
    • Affects Version/s: 1.7DR#2
    • Fix Version/s: None
    • Component/s: ICE-Components
    • Labels:
      None
    • Environment:
      Unknown
    • Workaround Exists:
      Yes
    • Workaround Description:
      Hide
      Bind the component and programmatically set the value on the component (each time the contents of the component changes):

      dataTable.setValue(list);
      Show
      Bind the component and programmatically set the value on the component (each time the contents of the component changes): dataTable.setValue(list);

      Description

      If you have an outer panelSeries and an inner panelSeries, and they're both showing lists of data, and you dynamically change the lists, it seems that they're somehow keeping around old information that keeps them from properly rendering the new lists.

      This may affects ice:dataTable as well.

        Activity

        Hide
        Wladyslaw Bultrowicz added a comment - - edited

        ...six months later Mark, could you please describe the work-around with re-queuing INVOKE APPLICATION/UPDATE MODEL. Where (lifecycleListener?) and how to do it right? And what about the "enhancement to help developers side-step this issue"?

        Show
        Wladyslaw Bultrowicz added a comment - - edited ...six months later Mark, could you please describe the work-around with re-queuing INVOKE APPLICATION/UPDATE MODEL. Where (lifecycleListener?) and how to do it right? And what about the "enhancement to help developers side-step this issue"?
        Hide
        Mark Collette added a comment -

        Ok, let's say you have a rowSelector and input components, and need the rowSelector's selectionListener to be called in INVOKE_APPLICATION, so that the input components' submittedValues will be pushed into the bean, in UPDATE_MODEL, before the selectionListener is called.

        The original solution was to do:

        public void selectionListener(RowSelectorEvent event) {
        if(!event.getPhaseId().equals(javax.faces.event.PhaseId.INVOKE_APPLICATION))

        { event.setPhaseId(javax.faces.event.PhaseId.INVOKE_APPLICATION); event.queue(); return; }

        // Now do your processing
        }

        Then we added a feature to rowSelector, where you could set immediate="false" on it, and the selectionListener would be called in INVOKE_APPLICATION for you, without the re-queue code.

        But, for other components, like input components and their valueChangeListener, there was no easy way of having them be called in INVOKE_APPLICATION. In ICEfaces 1.8 RC1 we introduced the ice:setEventPhase component, which is the general solution for changing what phase events will be broadcast in, and so the phase the listeners will be invoked in. You can still use immediate, but setEventPhase makes it unnecessary.

        Show
        Mark Collette added a comment - Ok, let's say you have a rowSelector and input components, and need the rowSelector's selectionListener to be called in INVOKE_APPLICATION, so that the input components' submittedValues will be pushed into the bean, in UPDATE_MODEL, before the selectionListener is called. The original solution was to do: public void selectionListener(RowSelectorEvent event) { if(!event.getPhaseId().equals(javax.faces.event.PhaseId.INVOKE_APPLICATION)) { event.setPhaseId(javax.faces.event.PhaseId.INVOKE_APPLICATION); event.queue(); return; } // Now do your processing } Then we added a feature to rowSelector, where you could set immediate="false" on it, and the selectionListener would be called in INVOKE_APPLICATION for you, without the re-queue code. But, for other components, like input components and their valueChangeListener, there was no easy way of having them be called in INVOKE_APPLICATION. In ICEfaces 1.8 RC1 we introduced the ice:setEventPhase component, which is the general solution for changing what phase events will be broadcast in, and so the phase the listeners will be invoked in. You can still use immediate, but setEventPhase makes it unnecessary.
        Hide
        Wladyslaw Bultrowicz added a comment -

        Actually I had the problem with BooleanCheckboxes in the <ice:dataTable>. If the underlying model changed (values were get and set properly), and the number of checkboxes stayed the same the view didn't reflect the model. I hacked it temporary by adding the valueChangeListener like:

        public void valueChangeListener(ValueChangeEvent event){
        if(!event.getPhaseId().equals(javax.faces.event.PhaseId.INVOKE_APPLICATION))

        { event.setPhaseId(javax.faces.event.PhaseId.INVOKE_APPLICATION); event.queue(); return; }

        HtmlSelectBooleanCheckbox checkbox = (HtmlSelectBooleanCheckbox) event.getSource();
        checkbox.setId("checkbox" + checkboxId++); //change of id forces icefaces to redraw the component
        }

        Is there any other (proper) way to force the icefaces to redraw the component? I know that ASP.NET controls have Render() method.

        Show
        Wladyslaw Bultrowicz added a comment - Actually I had the problem with BooleanCheckboxes in the <ice:dataTable>. If the underlying model changed (values were get and set properly), and the number of checkboxes stayed the same the view didn't reflect the model. I hacked it temporary by adding the valueChangeListener like: public void valueChangeListener(ValueChangeEvent event){ if(!event.getPhaseId().equals(javax.faces.event.PhaseId.INVOKE_APPLICATION)) { event.setPhaseId(javax.faces.event.PhaseId.INVOKE_APPLICATION); event.queue(); return; } HtmlSelectBooleanCheckbox checkbox = (HtmlSelectBooleanCheckbox) event.getSource(); checkbox.setId("checkbox" + checkboxId++); //change of id forces icefaces to redraw the component } Is there any other (proper) way to force the icefaces to redraw the component? I know that ASP.NET controls have Render() method.
        Hide
        Mark Collette added a comment -

        The components are already redrawing themselves. As this Jira explains, the problem is that the UIData containers are storing the old values for the components. You have to call getSavedChildren().clear() on the UIData/UISeries parents if you update your model values.

        Show
        Mark Collette added a comment - The components are already redrawing themselves. As this Jira explains, the problem is that the UIData containers are storing the old values for the components. You have to call getSavedChildren().clear() on the UIData/UISeries parents if you update your model values.
        Hide
        Krashan Brahmanjara added a comment -

        To Wladyslaw Bultrowicz, immediate="false" on row selector didn't resolved your problem?
        In our master-detail view it helps.

        Show
        Krashan Brahmanjara added a comment - To Wladyslaw Bultrowicz, immediate="false" on row selector didn't resolved your problem? In our master-detail view it helps.

          People

          • Assignee:
            Unassigned
            Reporter:
            Mark Collette
          • Votes:
            10 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: