我正在創建標準的「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