Tutorial :Flex Datagrid within repeater - Data bind warning



Question:

In my Flex app I am using a repeater to show a report on my database data. On this report the user can "drill-down" on the data to show more detail. In order to make this easier on the eye I have a header label and then a datagrid within the repeater.

Whilst this works perfectly, because the dataprovider for the datagrid comes from an array in the repeaters dataprovider, it is causing the following warning:

Data binding will not be able to detect assignments to "report"

The warning is for this line:

<mx:DataGrid id="dgReport" dataProvider="{rptReport.currentItem.report}" rowCount="{rptReport.currentItem.report.length}">  

Below is my code, if anyone has any suggestions for how I can get rid of the warning/do this properly they will be most welcome!

<mx:Script>      <![CDATA[          [Bindable] private var reportProvider;            private function report_Handler(event:ResultEvent):void {              // Temp variables              var currentHeader:String = "";              var previousHeader:String = "";                // Retrieve PHP array              var reportPHP:Array = ArrayUtil.toArray(event.result);                // Create Flex array              var reportFlex:Array = [];              var reportFlex_dataGrid:Array = [];                // Loop through PHP array              for(var i:int = 0; i < reportPHP.length; i++) {                  // Retrieve current header                  currentHeader = reportPHP[i].header;                    // Clear array                  if (currentHeader != previousHeader) {                      reportFlex_dataGrid = [];                  }                    reportFlex_dataGrid.push({column1:reportPHP[i].column1, column2:reportPHP[i].column2, column3:reportPHP[i].column3});                                             }                // Add to repeater array              if (currentHeader != previousHeader) {                                            // Add to array                  reportFlex.push({header:reportPHP[i].header, report:reportFlex_dataGrid});              }                // Store previous headers              previousHeader = reportPHP[i].header;                // Add to combobox data provider              reportProvider = new ArrayCollection(reportFlex);          }                             ]]>  </mx:Script>    <mx:Repeater id="rptReport" dataProvider="{reportProvider}">      <mx:VBox>          <mx:Spacer height="5"/>            <mx:Label id="lblHeader" text="{rptReport.currentItem.header}"/>            <mx:DataGrid id="dgReport" dataProvider="{rptReport.currentItem.report}" rowCount="{rptReport.currentItem.report.length}">              <mx:columns>                  <mx:DataGridColumn headerText="Column1" dataField="column1"/>                  <mx:DataGridColumn headerText="Column2" dataField="column2"/>                  <mx:DataGridColumn headerText="Column3" dataField="column3"/>              </mx:columns>          </mx:DataGrid>      </mx:VBox>    </mx:Repeater>  


Solution:1

Data binding will not be able to detect assignments to "report"

Your dataProvider is rptReport.currentItem.report. Of this, rptReport, being an mxml element, is Bindable. The currentItem property of the Repeater component is also declared to be Bindable. The report property of the current item is not bindable - current item itself is just an object. Through this warning Flex is saying that if you alter the report of an already assigned object to something else, it won't be automatically reflected in the data grid.

In most cases you can safely ignore this type of warnings.

When you say x="{a.b.c.d}" in mxml, the guarantee is that flex will detect changes made to any of the four items in the chain (a, b, c and d) and update the value of x. In other words, x will change when a or a.b or b.c or c.d is changed. For this to work, Flex expects that all those four are declared bindable. If it finds any of these items to be not bindable, it will throw a warning. A property is bindable if it was declared using mxml or if it was declared with the [Bindable] metadata tag in ActionScript.

In most cases, one would be interested only in the changes to a or a.b. In your example, changes happen only when HTTPService is resend, in which case the dataProvider itself will change.


Solution:2

Dude, a little off-topic, but having a grid in a repeater sounds really busy. If you want to have a drill-down, pop it up or put it in a pane that's only visible in that mode.

Visually, the repeater is a pattern which the user can internalize. A grid inside that pattern is a lot harder to deal with. Scrolling the grid vs. scrolling the repeater will likely be frustrating, let alone Tab navigation.

Logistically, you are creating a lot of in-memory UI. I would worry about performance.

Consider using a List with a custom Item renderer instead of a repeater. I still would not put a grid in there, but it's worth the effort.

Cheers


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »