Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Почему возвращаются нули? (http://www.flasher.ru/forum/showthread.php?t=141166)

TOKIO 17.06.2010 17:58

Почему возвращаются нули?
 
Вот код одного из двух классов:

Код AS3:

internal class RandomItem {
 
 private var randomNum:int;
 private var instantName:String;
 private var items:XML;
 private var instantItem:XMLList;
 private static var QUANTITY_OF_ITEMS:int = 15;
 private var _getPosition:XMLList;
 private var _getTitle:XMLList;
 private var _getDescription:XMLList;
 
 public function RandomItem() {
 
  randomNum = NumberUtilities.random(1, QUANTITY_OF_ITEMS); // присваиваем переменной случайный номер
  instantName = "mcItem" + randomNum;
 
  // Создаем объект XML из файла Items.xml
  loadXML();
 }
 
 private function loadXML():void {
  var loader:URLLoader = new URLLoader();
  loader.dataFormat = URLLoaderDataFormat.TEXT;
  loader.addEventListener(Event.COMPLETE, completeLoaderListener);
  loader.load( new URLRequest( "Items.xml" ) );
 }
 
 private function completeLoaderListener(event:Event):void {
 items = new XML (event.target.data)
 instantItem = items.ITEM.(@flashname == instantName); // создаем xml лист с фильтрацией по атрибуту
 _getPosition = instantItem.ITEM.@position;
 _getTitle = instantItem.ITEM.TITLE;
 _getDescription = instantItem.ITEM.DESCRIPTION;
 }
 
 public function getFlashName():String {
  return instantName;
 }
 
 public function getPosition():String {
  return _getPosition;
 }
 
 public function getTitle():String {
  return _getTitle;
 }
 
 public function getDescription():String {
  return _getDescription;
 }
 
}

Items.xml также имеется. Вопрос что не так в этом коде и почему при вызове getPosition() getTitle() getDescription() возвращается null???

Хемуль 17.06.2010 18:03

2 TOKIO:
Когда именно возвращаются? У вас приватные переменные, используемые в указанных вами функциях инициируются в обработчике completeLoaderListener. Вы там, случайно, не пытаетесь их проверять раньше окончания загрузки?

Wolsh 17.06.2010 18:08

Это что - компилится? У Вас же типы не соответствуют.
Код AS3:

private var _getTitle:XMLList;

Код AS3:

 public function getTitle():String {
  return _getTitle;
 }


BlooDHounD 17.06.2010 18:17

Wolsh, видимо убран strict, и происходит конвертация.

TOKIO 17.06.2010 18:27

Цитата:

Сообщение от Хемуль (Сообщение 916302)
2 TOKIO:
Когда именно возвращаются? У вас приватные переменные, используемые в указанных вами функциях инициируются в обработчике completeLoaderListener. Вы там, случайно, не пытаетесь их проверять раньше окончания загрузки?

вот основной класс, где я запрашиваю переменные:

Код AS3:

public class Main extends MovieClip {
 
 public function Main() {
 
  var timer:Timer = new Timer (1000, 5);
  timer.addEventListener(TimerEvent.TIMER, timerListener);
  timer.start();
 }
 
 public function timerListener(event:TimerEvent):void {
 
  var _randomItem:RandomItem = new RandomItem();
  trace ( _randomItem.getFlashName() );
  trace ( _randomItem.getPosition() );
  trace ( _randomItem.getTitle() );
  trace (_randomItem.getDescription() );
 }
 
}

выводится:

Код:

mcItem9
null
null
null
mcItem13
null
null
null


Wolsh 17.06.2010 21:40

Т.е. Вы подождали секунду и начали загрузку xml.
Но окончания загрузки ждать не стали и сразу запросили данные из xml, которая еще не загрузилась.
Вот и null.

TOKIO 22.06.2010 13:17

Вот класс, который вытаскивает данные из XML:

Код AS3:

internal class RandomItem {
 
                private var randomNum:int;
                private var instantName:String;
                private var itemsXML:XML;
                private var instantItem:XMLList;
                private static var QUANTITY_OF_ITEMS:Number = 15; // количество item
                private var _getPosition:XMLList;
                private var _getTitle:XMLList;
                private var _getDescription:XMLList;
 
                public function RandomItem() {
 
                        randomNum = NumberUtilities.random(1, QUANTITY_OF_ITEMS); // присваиваем переменной случайный номер
                        instantName = "mcItem" + randomNum; // случайное имя
 
                        // Создаем объект XML из файла Items.xml
                        loadXML();
                }
 
                private function loadXML():void {
                        var loader:URLLoader = new URLLoader();
                        loader.dataFormat = URLLoaderDataFormat.TEXT;
                        loader.addEventListener(Event.COMPLETE, completeLoaderListener);
                        loader.load( new URLRequest( "Items.xml" ) );
                }
 
                private function completeLoaderListener(event:Event):void {
                        itemsXML = new XML (event.target.data);
                        instantItem = itemsXML.ITEM.(@flashname == instantName); // создаем xml лист с фильтрацией по атрибуту
                        _getPosition = instantItem.@position;
                        _getTitle = instantItem.TITLE;
                        _getDescription = instantItem.DESCRIPTION;
                        trace (_getPosition + " --  " + _getTitle + " -- " + _getDescription) // здесь всё ОК - возвращает то, что надо!
                }
 
                // получить имя случайного мувиклипа
                public function getFlashName():String {
                        return instantName;
                }
 
                // получить расположение случайного мувиклипа (horizontal или vertical)
                public function getPosition():String {
                        return _getPosition;
                }
 
                // получить случайное название
                public function getTitle():String {
                        return _getTitle;
                }
 
                // получить случайное описание
                public function getDescription():String {
                        return _getDescription;
                }
 
        }

А вот класс, который должен присваивать переменным значения, извлеченные предыдущим классом:

Код AS3:

public class Main extends MovieClip {
 
                public function Main() {
 
                        var _randomItem:RandomItem = new RandomItem();
                        trace ( _randomItem.getFlashName() );
                        trace ( _randomItem.getPosition() ); // возвращает null!
                        trace ( _randomItem.getTitle() ); // возвращает null!
                        trace ( _randomItem.getDescription() ); // возвращает null!
                }
 
        }

В чем я ошибся? И как правильно вытащить значения???

Добавлено через 5 часов 38 минут
Код можно не писать, хотя бы теоретически ответьте.

Wolsh 22.06.2010 19:12

"Счетчик" (видимо таймер) здесь был не при чем - от него вообще ничего не зависит.
Вы создаете новый экземпляр RandomItem и в следующей строчке начинаете трейсить параметры этого RandomItem. Хотя в Вашем (?) классе эти самые параметры получают значения только в обработчике окончания загрузки xml. Как Вы сами считаете, документ может загрузиться за 1/10000 секунды? Разве только с локального жесткого диска.

TOKIO 22.06.2010 19:25

Цитата:

Сообщение от Wolsh (Сообщение 917259)
"Счетчик" (видимо таймер) здесь был не при чем - от него вообще ничего не зависит.
Вы создаете новый экземпляр RandomItem и в следующей строчке начинаете трейсить параметры этого RandomItem. Хотя в Вашем (?) классе эти самые параметры получают значения только в обработчике окончания загрузки xml. Как Вы сами считаете, документ может загрузиться за 1/10000 секунды? Разве только с локального жесткого диска.

Я думал при создании экземпляра класса RandomItem он создается полностью, то есть RandomItem не создается пока не загрузится xml. Видимо это не так.

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

Wolsh 22.06.2010 22:07

Ну, например, такая распространенная схема - RandomItem в обработчике окончания загрузки xml ПОСЛЕ присвоения параметрам значений должен отправить событие (мол все готово, COMPLETE). Но для этого необходимо еще кое что сделать - вынести начало загрузки из конструктора в отдельный публичный метод (доп. load), иначе Вы не сможете подписаться на событие COMPLETE от RandomItem до старта загрузки. Т.е. работа с RandomItem должна получиться похожей на работу с классом XML на этапе загрузки -

Код AS3:

public class Main extends MovieClip {
 
    public function Main() {
        var _randomItem:RandomItem = new RandomItem();
        _randomItem.addEventListener(RandomItem.COMPLETE, onRandomItemComplete);
        _randomItem.load("Items.xml");
    }
    public function onRandomItemComplete(event:Event):void {
        var _randomItem:RandomItem = event.target as RandomItem;
        trace ( _randomItem.getFlashName() );
        trace ( _randomItem.getPosition() ); // возвращает null?
        trace ( _randomItem.getTitle() ); // возвращает null?
        trace ( _randomItem.getDescription() ); // возвращает null?
    }
}

Код AS3:

internal class RandomItem {
    public static const COMPLETE:String = "random_item_complete";
    ....
    public function RandomItem() {
        ....
        //  НЕ создаем объект XML из файла Items.xml
        // loadXML();
        ....
    }
    public function load(url:String):void {
        var loader:URLLoader = new URLLoader();
        loader.dataFormat = URLLoaderDataFormat.TEXT;
        loader.addEventListener(Event.COMPLETE, completeLoaderListener);
        loader.load( new URLRequest( url ) );
    }
private function completeLoaderListener(event:Event):void {
        ....
        _getPosition = instantItem.@position;
        _getTitle = instantItem.TITLE;
        _getDescription = instantItem.DESCRIPTION;
        ....
        dispatchEvent( new Event(RandomItem.COMPLETE) );
    }
}

Как-то так.

Добавлено через 4 минуты
Да, и надо RandomItem расширить от EventDispatcher конечно и импорты я опустил.


Часовой пояс GMT +4, время: 20:17.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.