Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   О классах и методах и немного про URLLoader (http://www.flasher.ru/forum/showthread.php?t=129532)

Gava 03.09.2009 18:10

О классах и методах и немного про URLLoader
 
Доброго времени суток.
Совсем уже отчаялся и решил-таки спросить.

Задача сводится к стандартной загрузке XML документа.
Итак дано:

есть два класса loadData и createObj

loadData - клас осуществляющий загрузку XML. Код привожу в кратце:

Код AS3:

var loadXMLdata:XML;
var loader:URLLoader = new URLLoader(new URLRequest("xml.xml"));
loader.addEventListener(Event.COMPLETE, getDataXML);
function getDataXML(e:Event):void
        {
                loadXMLdata = XML(e.target.data);
        }

второй класс createObj имеет лишь одну цель, а именно получить вот эту самую loadXMLdata из loadData и на этих данных уже сформировать экземпляр в конструкторе.

в принципе с задачей в плане кода я справился как мне кажется, но наткнулся на проблему которая уже имела место быть на форуме, но ответа я так и не нашел.
А именно - когда я обращаюсь как угодно к loadData толи через создание экземпляра, толи через прямое обращение к функции - я просто не успеваю загрузить данные в переменную.Ну и формирование экземпляра createObj соответсвенно летит в тар-тарары.
Как притормозить выполнение кода я так и не придумал.

Так вот в чем вопрос. Такой вариант реализации вообще имеет право на существование? Если нет то какие есть варианты? Для меня критично именно продолжение кода уже с загруженными данными. Затормозить ожиданием функции тоже нельзя, т.к. конструктор свои дела закрывает и все значения у меня null.

Ну всем кто уделит мне пару строк за ранее спасибо:)

evg1605 03.09.2009 19:01

Я правильно понял что loadData ты используешь следующим образом
Код AS3:

var ld:loadData = new loadData();
//и сразу же второй строчкой
createObj.use(ld);

Если так , то ты разумеется не дожидаешься загрузки.
createObj должен юзать loadData, только когда она ему просигналит :)
(т.е. подписавшись на событие), а событие должно генерироваться loadData сразу после строчки loadXMLdata = XML(e.target.data);
Если не правильно понял - напиши подробнее код.

amesqit 03.09.2009 19:07

А что мешает после получения в классе loadData сгенерировать событие, подписаться на него там где это необходимо и после вызова события сгенерированного в loadData создать экзепляр createObj на основе данных в loadXMLdata? Все что для этого надо почитать в хелпе про класс EventDispatcher и его метод dispatchEvent()

evg1605 03.09.2009 19:10

Ну так я за то и агитирую :)

Idon 03.09.2009 19:14

1)
Код AS3:

function getDataXML(e:Event):void
        {
                loadXMLdata = XML(e.target.data);
 
              //а вот тут нельзя создать экземпляр createObj?
 
        }

2)
Можно прямо в createObj загружать xml, но технология там будет такая же: "событие окончания загрузки->всё остальное".

3) Можно перед вызовом конструктора createObj проверять, завершилась ли загрузка, и если нет не создавать createObj (если его создание не критично или пользователь может самостоятельно генерировать попытки его создания. например по нажатию на кнопку).

4) не уверен, что получится, но можно попробовать написать супер-корявый код:
сделать бесконечный цикл, выходом из которого будет событие окончания загрузки.
(допустим, в цикле можно проверять переменную, которая после окончания загрузки меняется на то значение, которое удовлетворяет выходу из бесконечного цикла). Но даже если это и заработает, тут есть подводные камни: защита флеша от зацикливания (по-умолчанию, там вроде 15 сек дается), ситуация, когда загрузка не происходит. Плюс ко всему, я бы постеснялся писать такое))

amesqit 03.09.2009 19:20

Idon, особо нет смысла мешать в кучу загрузку и обработку данных, бесконечный цикл, нажатие на кнопку не выход, это глупо, если будет долго загружаться, то юзер замучается жать кнопку, а цикл будет ограничиваться 15 секундами, да и зачем изобретать велосипед, когда элементарно можно воспользоваться пользовательскими событиями, они для того и предназначены
P.S.: в варианте 4 загрузка xml не произойдет никогда, т.к. до завершения цикла другой код выполняться не будет, в том числе и обработка загрузки xml

evg1605 03.09.2009 19:21

4) не сработает, даже если не постесняешься, инициализация loadXMLdata будет происходить в том же потоке который ты циклишь

СлаваRa 03.09.2009 19:23

а вы перед XML не пробовали поставить new?

amesqit 03.09.2009 19:37

Цитата:

Сообщение от СлаваRa (Сообщение 848016)
а вы перед XML не пробовали поставить new?

тут идет преобразование типов, можете сами попробовать:

Код AS3:

var xml:XML = XML("<a><b><c/></b></a>")
trace(xml)

или
Код AS3:

var xml:XML =XML(<a><b><c/></b></a>)
trace(xml)


СлаваRa 03.09.2009 19:42

покажи весь код класса

Idon 03.09.2009 19:56

amesqit, откуда мне знать, какие у него задачи и когда именно требуется загружать обработчик. Если человек спрашивает про паузу в коде, значит вызов обработчика у него идет следом за созданием загрузчика, а может вообще у него обработка кнопкой инициализируется...

На счёт 4 пункта понятно - загнался)

Gava 04.09.2009 04:20

такс....ну свою ошибку осознал...на самом деле надо было побольше кода:)
ещё раз попробую донести свою задачу.
Первый класс:

loadData

Код AS3:

public class loadData
{
    public var loadXMLdata:XML;
    public function loadData(nameXML)
    {
          var loader:URLLoader = new URLLoader(new URLRequest(nameXML));
          loader.addEventListener(Event.COMPLETE, getDataXML);
          function getDataXML(e:Event):void
            {
                  loadXMLdata = XML(e.target.data);
            }
    }
}

второй класс createObj

import loadData;

Код AS3:

public class createObj
{
    public var getXML:XML;
    public function createObj(nameXML)
    {
          var loadXML:loadData = new loadData(nameXML);
          getXML = loadXML.loadXMLdata;
 
          //дальнейшие действия с полученными данными
    }
}

вот так вот выглядит моя цель...
создавать объект после совершенного события не подходит так как в конструктор передается имя загружаемой XMLки да и к тому же loadData не должен быть прикручен ни к какому классу, а должен быть универсальным загрузчиком XML данных для любого обратившего к нему классу...

попробовал вынести отдельным методом

Код AS3:

getXML = loadXML.functionLoadXMLdata(nameXML);

но тогда функция functionLoadXMLdata должна возвращать данные типа XML, а сам метод получения по евенту подразумевает вызов сторонней функции getDataXML и опять ступор так как functionLoadXMLdata успевает мне вернуть значение null до того как getDataXML присвоит ему значение.

Ну в общем надеюсь понятен смысл задумки :)

З.Ы.
Idon все корявые коды с циклами я перепробовал, ничего кроме зависшего компа я не добился :)

Obi 04.09.2009 11:31

Код:

var loadXML:loadData = new loadData(nameXML);
          getXML = loadXML.loadXMLdata;

Да что вы все пытаетесь null-то присвоить? Подписывайтесь на события. Когда данные загрузятся, тогда и работайте с ними.

Gaen 04.09.2009 12:28

Код AS3:

public class createObj
{
    public var getXML:XML;
    public function createObj(nameXML)
    {
          //Запускается асинхронная загрузка данных
          var loadXML:loadData = new loadData(nameXML);
 
          //На данный момент ещё ничего не загрузилось
          getXML = loadXML.loadXMLdata;
 
          //Всё ещё не загрузилось
 
          //До сих пор не загрузилось
 
          //Да и вообще не загрузится, внутри этого блока доступ к данным получить нельзя
    }
}

Данные становятся доступными после того, как выстреливает Event.COMPLETE у URLLoader'a, поэтому вам нужно подписаться на это событие. Если не хочется всё мешать в одну кучу и выделить специальный класс, который грузит и потом хранит данные, то лучший вариант - чтобы он испускал событие. Но я бы не стал это всё городить, так как в классе, который его использует, в итоге будет весь тот же самый код: переменная для данных, установка обработчика, инициализация загрузки и сам обработчик.

Gava 04.09.2009 13:00

эммм...ну так что данный способ на корню глухая затея?
какой тогда вообще существует способ построения кода на основе полученных данных?
не подгрузки картинок или чего то ещё, а именно загрузки конфигов из внешних источников для построения всего класса аля сцены аля сайта аля портала...

просто у меня в голове не укладывается понятие модульности если одно и тоже повторяющееся действие нельзя объединить в один класс аля метод:(

да и многоуважаемые мною господа из adobe не могли ведь предусмотреть асинхронный метод не предусмотрев синхронный?:) Или я слишком их идеализирую?:)

Gaen 04.09.2009 13:49

Синхронный метод есть в AIR :) А во флэше приходится довольствоваться только асинхронным. Использование событий - совершенно нормальная практика.

Idon 04.09.2009 13:51

Если обойтись без доп. событий, то можно так попробовать:

Код AS3:

public class loadData
{
    public var loader:URLLoader;
    public function loadData(nameXML):void {
          loader = new URLLoader(new URLRequest(nameXML));
    }
}

Код AS3:

public class createObj
{
    private var getXML:XML;
    private var loadXML:loadData
    public function createObj(nameXML):void {
          loadXML = new loadData(nameXML);
          loadXML.loader.addEventListener(Event.COMPLETE, getDataXML);
    }
    private function getDataXML(e:Event):void {
          loadXML.loader.removeEventListener(Event.COMPLETE, getDataXML);
          getXML = XML(e.target.data);
 
          //дальнейшие действия с полученными данными
    }
}

Хотя так смысл в классе loadData вообще пропадает)

Obi 04.09.2009 14:05

Цитата:

не подгрузки картинок или чего то ещё, а именно загрузки конфигов из внешних источников для построения всего класса аля сцены аля сайта аля портала...
Не понимаю, что вам не понятно? Начали загружать настройки, поставили прелоадер с надписью «загрузка настроек». Настройки загрузились, вы их распарсили и стройте спокойно на их основе свой UI.

Gava 04.09.2009 14:26

Ну если так то все понятно, вроде бы...
Просто при реализации натолкнулся на бесконечное повторение одной и той же функции, а именно подгрузки XML через URLLoader и вот решил эти 4 строчки вынести в 1 класс ну и юзать его при необходимости.
Как-то мне показалось что это лежит на поверхности и что отсутсвие в гугле готовых решений объясняется банальностью и тривиальностью что об этом даже никто не пишет:)


Ну в общем спасибо всем кто учавствовал в моем разочаровании в adobe:)


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

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