Apache flex 将行添加到Flex DataGrid而不更改dataProvider
我正在创建标准的单击添加行控件,但我真的不想用占位符弄脏数据提供程序,因为它绑定到模型,可能最终会出现在数据库中。是否有方法添加数据提供程序中未表示的行?我开始直接向listItems添加一个项目,但之后需要在rowInfo中添加一个项目,然后需要在rowMap中添加一个引用Apache flex 将行添加到Flex DataGrid而不更改dataProvider,apache-flex,datagrid,Apache Flex,Datagrid,我正在创建标准的单击添加行控件,但我真的不想用占位符弄脏数据提供程序,因为它绑定到模型,可能最终会出现在数据库中。是否有方法添加数据提供程序中未表示的行?我开始直接向listItems添加一个项目,但之后需要在rowInfo中添加一个项目,然后需要在rowMap中添加一个引用 有什么好主意吗?好的,它不好看也不整洁,但很管用 利用SOTC的一些示例: 基本上,我使用两个集合。我扩展了DataGrid并为sourceDataProvider添加了另一个属性。在这个setter中,我为dataPr
有什么好主意吗?好的,它不好看也不整洁,但很管用 利用SOTC的一些示例: 基本上,我使用两个集合。我扩展了DataGrid并为sourceDataProvider添加了另一个属性。在这个setter中,我为dataProvider创建了一个新的ArrayCollection,这样它们就不再链接。我还调用添加占位符对象,以便单击此处添加到数据提供程序
[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();
}
请记住,我正在控制在itemEditor中调用editEnd的时间。我有一个按钮点击运行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;
}
}
好吧,它不好看也不整洁,但它很管用 利用SOTC的一些示例: 基本上,我使用两个集合。我扩展了DataGrid并为sourceDataProvider添加了另一个属性。在这个setter中,我为dataProvider创建了一个新的ArrayCollection,这样它们就不再链接。我还调用添加占位符对象,以便单击此处添加到数据提供程序
[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();
}
请记住,我正在控制在itemEditor中调用editEnd的时间。我有一个按钮点击运行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...
}
}
答案是编写自己的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...
}
}
没有扩展DataGrid就不行
我怀疑向数据提供程序添加一行也不能解决问题。DataGrid使用渲染器循环,这意味着它只为屏幕上的项目创建行。我假设如果您希望始终显示新的项目行。由于渲染器回收,用户将始终必须滚动到列表底部才能找到“newitem”行 必须扩展数据网格
我怀疑向数据提供程序添加一行也不能解决问题。DataGrid使用渲染器循环,这意味着它只为屏幕上的项目创建行。我假设如果您希望始终显示新的项目行。由于渲染器回收,用户将始终必须滚动到列表底部才能找到“newitem”行 一个好问题+1。这是一个非常实用的用例,我已经考虑过很多次了。希望有人有一个好的答案…一个好问题+1。这是一个非常实用的用例,我已经考虑过很多次了。希望有人能给出一个好的答案……如果您实现ICollectionView而不是IList,它可能会工作得更好。ListBase将ILists包装在ListCollectionView中,在该视图中使用ICollectionView时未加修饰。如果我将另一个控件绑定到网格的数据提供程序,它将永远不会显示人造行?听起来我需要更多地了解IList是如何使用的……在我的示例中,您不会将控件绑定到网格的DP,而是绑定到sourceCollection。这样,两个控件共享同一个源,但网格中添加了一行或多行。。。它具有相当的可扩展性。如果实现ICollectionView而不是IList,它可能会工作得更好。ListBase将ILists包装在ListCollectionView中,在该视图中使用ICollectionView时未加修饰。如果我将另一个控件绑定到网格的数据提供程序,它将永远不会显示人造行?听起来我需要更多地了解IList是如何使用的……在我的示例中,您不会将控件绑定到网格的DP,而是绑定到sourceCollection。这样,两个控件共享同一个源,但网格中添加了一行或多行。。。它是相当可扩展的