[ 
https://issues.apache.org/jira/browse/FLEX-35197?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15784994#comment-15784994
 ] 

Devsena edited comment on FLEX-35197 at 12/29/16 10:36 AM:
-----------------------------------------------------------

I spent sometime on this implementing runtime binding updates to DataGrid 
component started with Peter's initial suggestion to extend custom 
_DataItemRendererFactoryForArrayListData_ and _DataProviderChangeNotifier_ 
classes. My target was to implement runtime binding updates to DataGrid 
component (which was missing in FlexJS) but not breaking the PAYG ideology it 
has. I started with two said classes (by Peter) as my initiation point.

*PNDataProviderChangeNotifier:* I extended _DataProviderChangeNotifier_ with 
custom event listening to dataProvider/ArrayList class as the existing 
"itemAdded", "itemRemoved" and "itemUpdated" event wasn't sufficient for this 
of our needs. The newer event listening is based on 
{{HTML/flex/org/apache/flex/events/ItemAddedEvent.as}} class which also has an 
_item_ field that meets our requirement. This is the very initiation point to 
make the DataGrid works per it's collection change at runtime - *if the bead 
not added the DataGrid continue to work as PAYG*.

*PNArrayList:* We found that existing ArrayList class wasn't sufficient for our 
needs; It do tells when an item being updated or added or removed by it's 
"itemUpdated", "itemAdded" or "itemRemoved" respectively, but it has no way to 
tell which item being updated or added or removed. {{PNArrayList}} extended by 
ArrayList class, dispatches that piece of information which is critical for our 
needs to update particular indexed item in DataGrid _without_ re-creating whole 
list components it has every time. The events are listened by 
{{PNDataProviderChangeNotifier}} which eventually informs the 
_DataItemRendererFactoryForArrayListData_ with specific information to 
update/delete/add an item. 

*DataItemRendererFactoryForArrayListData:* For some unknown reason I couldn't 
able to extend this class. Even there were no errors and SWF also ran pretty 
fine _if_ I extend it, HTML output always found distorted. I do not know why, 
maybe there are other classes which directly referring 
_DataItemRendererFactoryForArrayListData_ instead of 
_PNDataItemRendererFactoryForArrayListData_ class. I found the following 
distortion when ran as HTML in browser:
!distortedui.png!

Thus, I choose to modify the original _DataItemRendererFactoryForArrayListData_ 
class only and adds my piece of codes; suggestions are welcome to make it a 
custom class resolving the UI issue in HTML output. 

The _DataItemRendererFactoryForArrayListData_ class is now listens to the 
events that fired by _PNDataProviderChangeNotifier_ and therefore reacts to 
update or add or remove any particular row in it's DataGroup with custom 
functions. (In original FlexJS design, 
_DataItemRendererFactoryForArrayListData_ only listens to "itemAdded", 
"itemRemoved" and "itemUpdated" events and re-creates all the list components 
it has which we found maybe costly in HTML run)

*PNDataGroup:* Extended by _DataGroup_ class. I require to extend it because 
the class didn't had any _addItemAt_ method in original source. Directly 
calling _addItemAt_ method (without overriding it in _DataGroup_) we found some 
UI problems; thus we choose to extend the class and add our own _addItemAt_ 
method.

*PNListSingleSelectionMouseController:* Extended by 
_ListSingleSelectionMouseController_. I noticed the original class was setting 
rollover-index and selected-index property by an static value stored in _index_ 
property. This was anyway Okay for PAYG, but when a row been removed or added 
in-between in runtime update scheme, the stored _index_ property to each row 
property became wrong. Thus I extended the class to update the rollover-index 
and selected-index property based upon it's _data_ index in the dataProvider 
collection.

Except above classes, _ItemAddedEvent.as_ also added in {{Core}} package so 
_PNArrayList_ class can access it from it's location. 

With my POC project, I tested following things were working fine with these new 
implementation, and I confirm recreation of complete list (inside _DataGroup_ 
or _DataItemRendererFactoryForArrayListData_) never fires when updating, too:
|| Method || Works ||
| arrayList._addItem_ | Ok |
| arrayList._addItemAt_ | Ok |
| arrayList._removeItem_ | Ok |
| arrayList._removeItemAt_ | Ok |
| arrayList._setItemAt_ | Ok |

I've attached herewith the changed classes (*PNSource.zip*) for Apache's 
review, if we can incorporate without hurting it's PAYG ideology, or just for 
suggestion. I'm also attaching the POC project with compiled SDK SWCs 
(*DataGridPOC.zip*) for an quick test by anyone.

*DataGridPOC.zip* contains both the POC project and compiled SWCs. Please, 
overwrite the following SWC files at 
{{apache-flex-flexjs-0.8.0-bin\frameworks\libs}}:
- Core.swc
- Collections.swc
- HTML.swc

I'm not exactly sure if following files also required for effectively test the 
changes, but you can overwrite this following files too at 
{{apache-flex-flexjs-0.8.0-bin\frameworks\js\FlexJS\libs}}:
- CoreJS.swc
- CollectionsJS.swc
- HTMLJS.swc

It'd be good to hear Peter and others' view on this.


was (Author: santanu4ver):
I spent sometime on this implementing runtime binding updates to DataGrid 
component started with Peter's initial suggestion to extend custom 
_DataItemRendererFactoryForArrayListData_ and _DataProviderChangeNotifier_ 
classes. My target was to implement runtime binding updates to DataGrid 
component (which was missing in FlexJS) but not breaking the PAYG ideology it 
has. I started with two said classes (by Peter) as my initiation point.

*PNDataProviderChangeNotifier:* I extended _DataProviderChangeNotifier_ with 
custom event listening to dataProvider/ArrayList class as the existing 
"itemAdded", "itemRemoved" and "itemUpdated" event wasn't sufficient for this 
of our needs. The newer event listening is based on 
{{HTML/flex/org/apache/flex/events/ItemAddedEvent.as}} class which also has an 
_item_ field that meets our requirement. This is the very initiation point to 
make the DataGrid works per it's collection change at runtime - *if the bead 
not added the DataGrid continue to work as PAYG*.

*PNArrayList:* We found that existing ArrayList class wasn't sufficient for our 
needs; It do tells when an item being updated or added or removed by it's 
"itemUpdated", "itemAdded" or "itemRemoved" respectively, but it has no way to 
tell which item being updated or added or removed. {{PNArrayList}} extended by 
ArrayList class, dispatches that piece of information which is critical for our 
needs to update particular indexed item in DataGrid _without_ re-creating whole 
list components it has every time. The events are listened by 
{{PNDataProviderChangeNotifier}} which eventually informs the 
_DataItemRendererFactoryForArrayListData_ with specific information to 
update/delete/add an item. 

*DataItemRendererFactoryForArrayListData:* For some unknown reason I couldn't 
able to extend this class. Even there were no errors and SWF also ran pretty 
fine _if_ I extend it, HTML output always found distorted. I do not know why, 
maybe there are other classes which directly referring 
_DataItemRendererFactoryForArrayListData_ instead of 
_PNDataItemRendererFactoryForArrayListData_ class. I found the following 
distortion when ran as HTML in browser:
!distortedui.png!

Thus, I choose to modify the original _DataItemRendererFactoryForArrayListData_ 
class only and adds my piece of codes; suggestions are welcome to make it a 
custom class resolving the UI issue in HTML output. 

The _DataItemRendererFactoryForArrayListData_ class is now listens to the 
events that fired by _PNDataProviderChangeNotifier_ and therefore reacts to 
update or add or remove any particular row in it's DataGroup with custom 
functions. (In original FlexJS design, 
_DataItemRendererFactoryForArrayListData_ only listens to "itemAdded", 
"itemRemoved" and "itemUpdated" events and re-creates all the list components 
it has which we found maybe costly in HTML run)

*PNDataGroup:* Extended by _DataGroup_ class. I require to extend it because 
the class didn't had any _addItemAt_ method in original source. Directly 
calling _addItemAt_ method (without overriding it in _DataGroup_) we found some 
UI problems; thus we choose to extend the class and add our own _addItemAt_ 
method.

*PNListSingleSelectionMouseController:* Extended by 
_ListSingleSelectionMouseController_. I noticed the original class was setting 
rollover-index and selected-index property by an static value stored in _index_ 
property. This was anyway Okay for PAYG, but when a row been removed or added 
in-between in runtime update scheme, the stored _index_ property to each row 
property became wrong. Thus I extended the class to update the rollover-index 
and selected-index property based upon it's _data_ index in the dataProvider 
collection.

Except above classes, _ItemAddedEvent.as_ also added in {{Core}} package so 
_PNArrayList_ class can access it from it's location. 

With my POC project, I tested following things were working fine with these new 
implementation, and I confirm recreation of complete list (inside _DataGroup_ 
or _DataItemRendererFactoryForArrayListData_ never fires when updating, too):
|| Method || Works ||
| arrayList._addItem_ | Ok |
| arrayList._addItemAt_ | Ok |
| arrayList._removeItem_ | Ok |
| arrayList._removeItemAt_ | Ok |
| arrayList._setItemAt_ | Ok |

I've attached herewith the changed classes (*PNSource.zip*) for Apache's 
review, if we can incorporate without hurting it's PAYG ideology, or just for 
suggestion. I'm also attaching the POC project with compiled SDK SWCs 
(*DataGridPOC.zip*) for an quick test by anyone.

*DataGridPOC.zip* contains both the POC project and compiled SWCs. Please, 
overwrite the following SWC files at 
{{apache-flex-flexjs-0.8.0-bin\frameworks\libs}}:
- Core.swc
- Collections.swc
- HTML.swc

I'm not exactly sure if following files also required for effectively test the 
changes, but you can overwrite this following files too at 
{{apache-flex-flexjs-0.8.0-bin\frameworks\js\FlexJS\libs}}:
- CoreJS.swc
- CollectionsJS.swc
- HTMLJS.swc

It'd be good to hear Peter and others' view on this.

> [FlexJS] Data-binding is broken or not implemented in DataGrid component
> ------------------------------------------------------------------------
>
>                 Key: FLEX-35197
>                 URL: https://issues.apache.org/jira/browse/FLEX-35197
>             Project: Apache Flex
>          Issue Type: Question
>    Affects Versions: Apache FlexJS 0.8.0
>            Reporter: Devsena
>            Assignee: Peter Ent
>            Priority: Critical
>         Attachments: DataGridPOC.zip, PNSource.zip, distortedui.png, src.zip
>
>
> (I've took the _DataGrid_ example that supplied within the nightly build of 
> 0.8.0 FlexJS SDK bundle, and I tried all my tests in that project only)
> h3.Requirement
> Binding is a strong feature in Flex technology. As an user I also do expect 
> that FlexJS will also empowers us with the same strength developing projects. 
> While testing _DataGrid_ example that supplies within SDK bundle, I noticed 
> that pay-as-you-go view only available but no actual run-time data binding 
> (as far I tested); which is the strength that I was talking about. Is 
> run-time data-binding (by any _beads_ or any other way) to DataGrid component 
> is at all available yet? 
> In the following tests I tried to update one row object's (_Product_) one 
> particular field (_image_) value, to see it's change in row renderer, at 
> run-time. 
> I also tried to add or delete an item to it's _dataProvider_ collection to 
> see their changes in DataGrid UI.
> h3.Actual Result
> Run-time data update to collection list not affecting to DataGrid UI.
> h3.How I Tested
> I've attached the source ZIP that supplied within SDK bundle and I modified 
> few codes to test my requirement.
> The example consists of a DataGrid, and few buttons as follows:
> - Replace Array - replace the entire model with a new Array
> - Update Entry - Update the image for the first entry
> - Add Entry - Add a new entry to the end of the list
> - Remove Entry - Remove the first entry
> - Refresh - this recreates the array and saves it to the model. This forces 
> the DataGrid to update by the same method as Replace Array
> "Replace Array" and "Refresh" worked fine. "Refresh" is a possible workaround 
> for data update to grid UI, but it is inefficient for a real application. The 
> other buttons did not cause DataGrid UI to update. The places which I've 
> changed as follows. 
> *Product.as*
> {code}
> // since I was trying to update one field at least to DataGrid UI, I added 
> get/set methods to the _image_ field
> private var _image:String;
> [Bindable(event="imageChanged")]
> public function get image():String
> {
>       return _image;
> }
>               
> public function set image(value:String):void
> {
>       if (value != _image)
>       {
>               _image = value;
>               dispatchEvent(new Event("imageChanged"));
>       }
> }
> {code}
> *MyInitialView.mxml*
> {code}
> // Replacing or recreating the collection list
> private function replaceArray():void
> {     
>       // Only this part worked when SimpleBinding used rather than 
> ConstantBinding
>       ProductsModel(applicationModel).productList = new ArrayList([new 
> Product("ps220","Weejets",35,190,"assets/smallorangerect.jpg")]);
>                               
>       writeStatus();
> }
> // Update an entry to the collection
> private function updateEntry():void
> {
>       // This part not working or updating to DataGrid UI either
>       /*ProductsModel(applicationModel).productList.source[1] = tmp;
>       ProductsModel(applicationModel).dispatchEvent(new 
> Event("propertyChange"));*/
>       // This part not working or updating to DataGrid UI
>       var tmp:Product = 
> ProductsModel(applicationModel).productList.getItemAt(0) as Product;
>       tmp.image = "Modified Text";
>                               
>       writeStatus();                          
> }
> // Adding an item to the collection list
> private function addEntry():void
> {
>       // Add a new entry to the list
>       idCounter++;
>       ProductsModel(applicationModel).productList.addItem(new 
> Product("product" + idCounter, "Added" + idCounter, 35, 190, 
> "assets/smallorangerect.jpg"));
>                               
>       writeStatus();
> }
> // Removing an item from the collection list
> private function removeEntry():void
> {
>       // remove the first item
>       ProductsModel(applicationModel).productList.removeItemAt(0);
>                               
>       writeStatus();
> }
> // Refreshing the collection to datagrid
> private function refresh():void
> {
>       // force an update setting the model to the same value it already has.  
> See replaceArray()
>                               
>       // this was insufficient to trigger the update:
>       // ProductsModel(applicationModel).productList = 
> ProductsModel(applicationModel).productList;
>                               
>       // Since there was NO refresh logic to ArrayList or DataGrid component, 
> we only do a brute refresh to the list
>       var oldArray:ArrayList = ProductsModel(applicationModel).productList;
>       var newArray:ArrayList = new ArrayList();
>       var index:int;
>       for (index = 0; index < oldArray.length; index++) {
>               newArray.addItem(oldArray.getItemAt(index));
>       }
>                               
>       ProductsModel(applicationModel).productList = newArray;
>       writeStatus();
> }
> ...
> // DataGrid ConstantBinding bead replaced with SimpleBinding
> <js:DataGrid id="dataGrid" x="20" y="30" width="400" height="300" 
> change="dataGridChange()" rowHeight="30">
>               <js:beads>
>                       <js:SimpleBinding sourceID="applicationModel"
>                                                         
> sourcePropertyName="productList" destinationPropertyName="dataProvider" 
> eventName="propertyChange"/>
> ...
> {code}
> I also created a new MXML based _DataItemRenderer_ component to see if 
> binding is working anyway: *ProductItemRendererMXML.mxml*; But it didn't 
> worked either. 
> I discussed this at dev mailing-list 
> (http://apache-flex-development.2333347.n4.nabble.com/Why-same-files-exists-in-multiple-places-td56983.html)
>  where Alex suggested that a chain of specific beads usage may help this 
> feature, but he wasn't sure if such beads already developed or not. 
> Is there any such beads or procedure already available, or, in-development? 



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to