开发者

Add row to Flex DataGrid without changing dataProvider

开发者 https://www.devze.com 2023-01-18 18:38 出处:网络
I am creating the standard \"Click to add row\" control but I really don\'t want to dirty the dataProvider with a \"placeholder\" since it is bound to the model and could end up in the database. Is th

I am creating the standard "Click to add row" control but I really don't want to dirty the dataProvider with a "placeholder" since it is bound to the model and could end up in the database. Is there a way to add a row that isn't represented in the dataProvider? I started down the road of adding an item directly to listItems but then that ne开发者_运维技巧eded an item in rowInfo and then that need a reference in rowMap....

Any ideas?


OK, it isn't nice and neat but it works.

Working off of some of SOTC's example: http://www.switchonthecode.com/tutorials/adding-dynamic-rows-to-flex-datagrid

Basically, I am using two collections. I extended DataGrid and added another property for sourceDataProvider. In the setter for this I create a new ArrayCollection for the dataProvider so they are no longer "linked". I also make a call to add the "placeholder" object for "Click here to add" to the dataProvider.

[Bindable]
        public function get sourceDataProvider():ArrayCollection
        {
            return _sourceDataProvider;
        }

        public function set sourceDataProvider(value:ArrayCollection):void
        {
            _sourceDataProvider= value;
             dataProvider = new ArrayCollection(value.source.concat());
             addPlaceholderItem();
        }

When the itemEditor is ready to commit the values, I just manually update the _sourceDataProvider. Don't try to use the setter, add to the private copy. At this point, the placeholder item has now been edited so we need to call the method again for creating a dummy object.

public function editEnd(e:DataGridEvent):void
        {
            // Adding a new task
            if(e.itemRenderer.data.condition != DUMMY_PLACEHOLDER_DATA && e.rowIndex == dataProvider.length - 1)
            {
                _sourceDataProvider.addItem(e.itemRenderer.data);
                destroyItemEditor();
                callLater(addPlaceholderItem);
                e.preventDefault();
            }
            dataProvider.refresh();
        }

Please keep in mind that I am controlling the when editEnd is called within my itemEditor. I have a button click running the method commitValues().

private function commitValues():void
        {
            //change the "data" here


            //force datagrid to endEdit
            var grid:DataGrid = listData.owner as DataGrid;
            if(grid)
            {
                grid.editedItemPosition = null;
                grid.selectedIndex = -1;
            }
        }


The answer is to write your own IList implementation and use that as the data provider for the list (which it takes by default).

Something like the below should work...

public class NewItemIList implements IList {

    public var sourceCollection : ICollectionView;
    public var additionalCollection : ICollectionView;
    public var additionalPositioning : String = "end";

    public override function get length() : int {
        return sourceCollection.length + additionalCollection.length;
    }

    public override function getItemAt( index : int = 0, prefetch : int = 0) : Object {
        if ( additionalPositioning  == "end" ) {
            if ( index > sourceCollection.length ) {
                return additionalCollection.getItemAt(index - sourceCollection.length );
            } else {
                return sourceCollection.getItemAt(index);
            }
        } else {
            do same for other positions...
        }
    }


Not without extending the DataGrid.

I suspect adding a row to your dataProvider won't solve the issue either. The DataGrid makes use of renderer recycling, which means it only creates rows for the item that are on the screen. I assume that if you want a "new item" row to always be displayed. Thanks to renderer recycling, the user would always have to scroll to the bottom of the list to find the 'new item' row.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号