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;
}
}