Apache flex 编译器警告我绑定不起作用,但为什么我运行应用程序它起作用!

Apache flex 编译器警告我绑定不起作用,但为什么我运行应用程序它起作用!,apache-flex,actionscript,adobe,Apache Flex,Actionscript,Adobe,下面的Flex应用程序生成编译器警告:数据绑定将无法检测到“dp”的赋值。这似乎是正确的,因为变量“dp”不是可绑定属性(没有[bindable]元数据标记)。我添加了一个按钮,当点击“dp”时,它会将项目附加到“dp”的后面。尽管编译器警告我不会看到对“dp”的更改,但每次单击按钮时,列表都会显示新项 我不明白为什么我可以看到新项目出现在列表中。有人能解释为什么尽管“dp”不可绑定,但它仍然有效吗 <mx:Application xmlns:mx="http://www.adobe.co

下面的Flex应用程序生成编译器警告:数据绑定将无法检测到“dp”的赋值。这似乎是正确的,因为变量“dp”不是可绑定属性(没有[bindable]元数据标记)。我添加了一个按钮,当点击“dp”时,它会将项目附加到“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)" /> 

尝试使用:

[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);

编译器的警告是正确的

编译器警告您,将不会检测到将
dp
的值从您指定的初始
ArrayCollection
更改为另一个
ArrayCollection
的赋值

但是,如果您不使用
dp
的值,只更改它的内容,则
将继续工作

这可能看起来微不足道,但这是一个重要的区别,它可能会导致应用程序中出现一些非常令人困惑的错误

将不会检测到变量
dp
的赋值。但是,对
阵列集合
s
列表
的更改将发生,因为它们会发送一个
集合更改事件

例如:

private-var-dp:ArrayCollection=new-ArrayCollection();
私有函数测试():void
{
//这里,我们不直接改变dp的值,
//相反,我们只是修改它的列表。
//数据组将显示字符串1、2
dp.补充(“一”)
dp.补充(“两个”)
//这里,我们通过指定一个
//新的阵列集合。
//不会检测到此更改,列表将继续显示
//上一个值的内容。
//此外,标签将显示字符串“长度:2”,
//尽管现在的长度显然是3。
dp=新阵列集合();
dp.增补(“塔希”);
dp.附加条款(“Rua”);
dp.附加条款(“Toru”);
}

这确实消除了编译器警告,但并没有改变我上面描述的行为(或解释它)。这相当令人困惑,因为即使是Adobe官方文档也似乎将ArrayCollection变量标记为可绑定的,因为它显然是多余的或不必要的。实际上,它不是多余的-这非常重要。我修改了我的答案,试图澄清到底发生了什么。调试绑定是一件痛苦的事情,所以请注意编译器向您发出的警告。+1表示不冗余。如果您知道该值不会改变,那么应该在dp声明中使用const而不是var。警告应该消失(至少,它可以与Flex4.5编译器一起工作)。
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}" />