我正在创建标准的“Click to add row”控件,但我真的不想用“占位符”来玷污dataProvider,因为它绑定到模型并最终可能在数据库中。有没有办法添加一个没有在dataProvider中表示的行?我开始将项目直接添加到listItems的道路上,但是之后需要rowInfo中的项目,然后需要rowMap中的参考...。在不改变dataProvider的情况下将行添加到Flex DataGrid中
任何想法?
我正在创建标准的“Click to add row”控件,但我真的不想用“占位符”来玷污dataProvider,因为它绑定到模型并最终可能在数据库中。有没有办法添加一个没有在dataProvider中表示的行?我开始将项目直接添加到listItems的道路上,但是之后需要rowInfo中的项目,然后需要rowMap中的参考...。在不改变dataProvider的情况下将行添加到Flex DataGrid中
任何想法?
好吧,它不好,整洁,但它的工作原理。
工作过的一些SOTC的例子: http://www.switchonthecode.com/tutorials/adding-dynamic-rows-to-flex-datagrid
基本上,我使用的两个集合。我扩展了DataGrid并为sourceDataProvider添加了另一个属性。在这个setter中,我为dataProvider创建了一个新的ArrayCollection,所以它们不再被“链接”。我还打电话为“点击这里添加”添加“placeholder”对象到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();
}
当itemEditor准备好提交值时,我只需手动更新_sourceDataProvider。不要尝试使用setter,添加到私人副本。此时,占位符项目现在已被编辑,所以我们需要再次调用该方法来创建虚拟对象。
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();
}
请记住,我正在控制editEnd在我的itemEditor中被调用的时间。我有一个按钮单击运行方法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;
}
}
答案是写自己的IList实现和使用,作为对列表中的数据提供程序(它需要在默认情况下)。下面
有点像应该工作...
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...
}
}
它可能会更好,如果你实现ICollectionView而不是IList。 ListBase将IList封装在ListCollectionView中,因为它使用未掺杂的ICollectionView。 – 2010-09-30 18:17:43
我认为这就是我基本上最终做的,尽管我只是习惯了ArrayCollection。如果我将另一个控件绑定到网格的dataProvider,它将永远不会显示虚拟行?听起来像我需要阅读更多关于如何使用IList ... – 2010-10-01 17:49:46
你不会将控件绑定到网格的DP,而是我的示例中的sourceCollection。这样,两个控件共享相同的源,但网格有添加的行(或行...它是相当可扩展的) – 2010-10-04 07:25:06
不是没有扩展数据网格。
我怀疑向dataProvider添加一行也不能解决问题。 DataGrid使用渲染器回收,这意味着它只会为屏幕上的项目创建行。我假设如果你想要一个“新项目”行总是显示。由于渲染器回收,用户将不得不滚动到列表底部以查找“新项目”行。
+1是一个很好的问题。这是一个非常实用的案例,我已经多次思考。希望有人有一个很好的答案... – 2010-09-30 17:08:49