下面的Flex应用程序生成编译器警告:数据绑定将无法检测到'dp'的分配。这似乎是正确的,因为变量'dp'不是可绑定属性(没有[Bindable]元数据标记)。我添加了一个按钮,当点击它时,它会将项目附加到'dp'的后面。虽然编译器警告我不会看到'dp'的更改,但每次单击按钮时列表都会显示新项目!
我不明白为什么我可以在列表中看到新项目。有人可以解释为什么这仍然有效虽然'dp'不可绑定吗?
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" minWidth="955" minHeight="600">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.rpc.events.ResultEvent;
private var arrayData:Array = [
{name:"banana", cat:"fruit", cost:0.99},
{name:"bread", cat:"bakery", cost:1.99},
{name:"orange", cat:"fruit", cost:0.52},
{name:"donut", cat:"bakery", cost:0.33},
{name:"apple", cat:"fruit", cost:1.05}];
private var dp:ArrayCollection = new ArrayCollection(arrayData);
private function onButtonClick(event:MouseEvent):void
{
var obj:Object = new Object();
obj.name="test";
obj.cat="testcat";
obj.cost=666;
dp.addItem(obj);
}
]]>
</mx:Script>
<mx:HorizontalList dataProvider="{dp}" labelField="name" columnWidth="100" width="80%" height="50"/>
<mx:Button label="Click me" click="onButtonClick(event)" />
答案 0 :(得分:5)
编译器的警告是正确的。
编译器警告您,将无法检测到将dp
的值从您指定的初始ArrayCollection
更改为另一个ArrayCollection
的分配。
但是,如果仅保留dp
的值,并且仅更改其内容,则<HorizontalList />
将继续有效。
这看起来似乎微不足道,但它是一个重要的区别,并且可以在您的应用程序中引发一些非常混乱的错误。
将无法检测到变量dp
的分配。但是,ArrayCollection
list
的更改将会发送CollectionChangeEvent
。
例如:
private var dp:ArrayCollection = new ArrayCollection();
private function test():void
{
// Here, we don't change the value of dp directly,
// instead we just modify it's list.
// The DataGroup will show the strings One,Two
dp.addItem("One")
dp.addItem("Two")
// Here, we change the actual value of dp, by assigning a
// new ArrayCollection to it.
// This change would not be detected, and the list would continue to show
// the contents of the previous value.
// Additionally, the label will show the string "Length: 2",
// even though the length is clearly now 3.
dp = new ArrayCollection();
dp.addItem("Tahi");
dp.addItem("Rua");
dp.addItem("Toru");
}
<s:DataGroup dataProvider="{dp}" />
<s:Label text="Length: {dp.length}" />
答案 1 :(得分:0)
尝试使用:
[Bindable("__NoChangeEvent__")]
private var dp:ArrayCollection = new ArrayCollection(arrayData);
如何在列表中添加元素,请参阅ListBase
的代码:
public function set dataProvider(value:Object):void
{
if (collection)
{
collection.removeEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler);
}
if (value is Array)
{
collection = new ArrayCollection(value as Array);
}
else if (value is ICollectionView)
{
collection = ICollectionView(value);
}
else if (value is IList)
{
collection = new ListCollectionView(IList(value));
}
else if (value is XMLList)
{
collection = new XMLListCollection(value as XMLList);
}
else if (value is XML)
{
var xl:XMLList = new XMLList();
xl += value;
collection = new XMLListCollection(xl);
}
else
{
// convert it to an array containing this one item
var tmp:Array = [];
if (value != null)
tmp.push(value);
collection = new ArrayCollection(tmp);
}
// get an iterator for the displaying rows. The CollectionView's
// main iterator is left unchanged so folks can use old DataSelector
// methods if they want to
iterator = collection.createCursor();
collectionIterator = collection.createCursor(); //IViewCursor(collection);
// trace("ListBase added change listener");
collection.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler, false, 0, true);
clearSelectionData();
var event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
event.kind = CollectionEventKind.RESET;
collectionChangeHandler(event);
dispatchEvent(event);
itemsNeedMeasurement = true;
invalidateProperties();
invalidateSize();
invalidateDisplayList();
}
所以看一下行:
collection.addEventListener(CollectionEvent.COLLECTION_CHANGE, collectionChangeHandler, false, 0, true);