Компилятор предупреждает меня, что привязка не будет работать, но почему я запускаю приложение, оно работает! - PullRequest
3 голосов
/ 23 июня 2011

Приложение 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)" /> 

Ответы [ 2 ]

5 голосов
/ 23 июня 2011

Компилятор указан правильно в своем предупреждении.

Компилятор предупреждает вас, что назначения, которые изменяют значение dp с исходного ArrayCollection, указанного вами на другое ArrayCollection, не будут обнаружены.

Однако, если вы оставите значение dp в покое и измените только его содержимое, ваш <HorizontalList /> продолжит работать.

Это может показаться тривиальным, ноэто важное различие, и оно может привести к некоторым очень запутанным ошибкам в будущем в вашем приложении.

Назначения переменной dp не будут обнаружены.Однако изменения в ArrayCollection s 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}" />
0 голосов
/ 23 июня 2011

Попробуйте использовать:

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