PDA

Просмотр полной версии : XML и отлов cобытия конца загрузки


Wazzabi
25.04.2012, 22:30
Доброе время суток!

Прошу помочь мне в разборе XML парсинга.
и так есть класс LoadConfig
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.net.URLLoader;
import flash.net.URLRequest;
/**
* ...
* @author 1
*/
public class LoadConfig extends Sprite
{
public var xml :XML;
public var loader : URLLoader;
public var fileName :String = "../config.xml";

public function LoadConfig()
{

loader = new URLLoader();
var request : URLRequest = new URLRequest(fileName);
loader.addEventListener(Event.COMPLETE, configLoadComplete);
loader.load(request);
}

public function configLoadComplete(e:Event):void
{

xml = XML(loader.data);
trace(xml);


}

public function TraceXML():void
{
trace(xml);
}
}

}

В Main'e создается экземпляр этого класса
var config :LoadConfig = new LoadConfig();
// и пытаюсь сразу получить данные из xml
config.TraceXML();
После запуска флешки в консоли пишется "null" и второй трейс моя xml'лька
т.е.

null
<list>
<params>
<param>width</param>
<value>800</value>
</params>
</list>

можете объяснить почему метод TraceXML выдает null? если даже вместо config.TraceXML() набрать, например trace(config.xml.params.value); выдает null....

Wolsh
25.04.2012, 23:00
Потому что еще ничего не загрузилось, это же очевидно.
На загрузку надо время, не то что в интернете, а даже в локальной системе загрузка происходит не мгновенно.

Wazzabi
26.04.2012, 09:02
Какой выход? Если сделать так:
loader.addEventListener(Event.COMPLETE, configLoadComplete);
обработать это событие в функиции configLoadComplete добавить
dispathEvent(new Event("CONFIG_LOADED"));
а в родителе отловить это событие? Есть какие варианты? как будет более грамотно?

Wolsh
26.04.2012, 09:28
1. Естественно, только по событию можно определить, что загрузка произошла и с данными можно работать.
2. Более грамотно будет не заниматься ерундой и не писать класс, который только делегирует обращения к URLLoader'у. То есть, у Вас эта идея возникла скорее всего вместе с уверенностью, что Ваш класс будет возвращать данные, не загрузив их. Но этого не будет. Посмотрите на свой класс и скажите, чем он отличается от самого URLLoader, кроме того что не предоставляет всей его функциональности?
Практически каждый флэшер хотя бы раз в жизни пытался написать свой XMLLoader. И я не исключение. Но смысл в этом появляется, только если Ваш класс будет делать что-то еще, то чего не делает URLLoader. Грузить коллекцию XMLек. Осуществлять перевод с WIN-1251. Создавать какой-то специфический Объект (по сути это уже не лоадер а парсер).
Что можно сделать по-другому? Ну например, можно использовать не События а коллбек, то есть отдавать вашему XMLLoaderу ссылку на функцию, которую надо вызвать по окончании загрузки (хорошо бы так же давать ссылку на функцию, которую надо вызвать, если загрузка завершилась ошибкой).
Но надо помнить, что коллбеки не очень кошерны в AS3, так как не дают возможности строгой типизации.

Wazzabi
26.04.2012, 10:40
Ну вообще я пытался написать класс, который грузит настройки и будет возвращать нужны данные в любом месте где это потребуется....

опять копаю не туда?:rolleyes:

Wolsh
26.04.2012, 11:44
))))
В смысле Вы сначала рожаете полста детишек, а потом при случае они звонят папе и спрашивают "Папа! А я негр или китаец? А сколько мне лет? А какого цвета на мне рубашка? А почему..?"
Семью надо планировать. Заранее. А потом в соответствии с планом заводить детишек.
Загрузили настройки и насоздавали объектов по этим настройкам. А не наоборот.

Newred
26.04.2012, 15:18
В самом "лоадере"
public function configLoadComplete(e:Event):void
{

xml = XML(loader.data);
trace(xml);
dispatchEvent(new Event("complete")); // Пускаем событие что загрузка завершена
}

В Main'e создается экземпляр этого класса

var config :LoadConfig = new LoadConfig();

// Слушаем событие , как только получим, выполнится функция xml_complite
config.addEventListener("complete", xml_complete) ;


function xml_complete(e:Event):void
{
config.TraceXML();
}


PS. Есть решения и получше, но желаю вам к ним дойти самостоятельно.
PS2. Привяжите main fla класс к файлу main.as и не пишите в кадрах

Wazzabi
27.04.2012, 11:03
PS2. Привяжите main fla класс к файлу main.as и не пишите в кадрах

а вот сдесь можете по-подробнее?

Newred
27.04.2012, 14:32
а вот сдесь можете по-подробнее?

Можно и даже нужно )
На ютубе видео (http://www.youtube.com/watch?v=W-O7aETqT3c&feature=youtu.be) как подключал
Во вложении пример.

Wazzabi
28.04.2012, 18:33
Newred, спасибо за урок. и сразу возникают несколько вопросов...

в чем плюсы этого способа?
Компиль где нажимать надо на FlashCS5? или в билдере?
Как тоже самое сделать на FlashDevelop'е?
Извиняюсь, что оффтоп вопросы

Wolsh
28.04.2012, 19:30
Я вообще не понял вашего диалога.
Newred, с чего Вы взяли, что Wazzabi пишет код в кадрах, если им представлен код класса? С чего Вы взяли, что у него есть какой-то Main.fla, что он вообще работает во Flash IDE?
1. Плюсы относительно чего? Разве что кода в кадрах. Код в классах это круче, чем в кадрах. Вот и весь плюс.
2. Билдер здесь только как текстовый редактор (я надеюсь) – написали текст класса, сохранили файл. Компилите в Flash CS5.
3. Зачем то же самое делать в FD?
Нет, ну если Вы действительно компилите в Flash CS5, то пожалуйста. Используете ФД просто как текстовый редактор для as-файлов. Либо выбираете при создании проекта тип ActionScript 3 -> Flash IDE Project, и вперед; для компиляции будет использоваться Flash IDE.
Вот только не понимаю, зачем это нужно.

Добавлено через 11 минут
Типа оффтоп: Видео просто шокировало. Надеюсь, выпитое перед съемкой пиво пошло на пользу чему-нибудь. Когда с пятой попытки "private function" было набрано, не смог удержаться от аплодисментов.
Сам способ очень заинтриговал. Я думал достаточно указать в поле "класс документа" пакет.имя класса, который будет "мейном". Рисование коричневого прямоугольника побороло всё, что я знал.

Wazzabi
28.04.2012, 20:13
Да я как-то пока не начинал изучать FlashCSx. Мне казалось, почти все можно сделать через код, изза этого мой выбор пал на написание кода в FD воздавая проект AS3.
PS я еще много не понимаю... простите за глупые вопросы =))

Wolsh
28.04.2012, 20:31
мой выбор пал на написание кода в FDИ это правильно. Когда понадобится зачем-нибудь Flash, тогда и воспользуетесь. Если денег не жалко будет))

ramshteks
29.04.2012, 01:21
Еще один, оффтоп)

Wolsh, ну код XMLLoader'а может быть очень общим и в то же время выполнять ряд очень удобных функций =)

Моя реализация, которой уже давненько пользуюсь, делает самый минимум, который на мой взгляд должен выполнять XMLLoader, это после загрузки проверять XML на валидность, в случае корявки выбрасывать об этом ивент, ну и предоставлять доступ непосредственно к уже созданному объекту с XML. Хорошая вещь, оказалась)

Wolsh
29.04.2012, 02:19
При этом Вы же отлично понимаете, что "проверка на валидность" происходит там же, где пытаетесь осуществить "доступ", автоматически?)) И всё это без проблем и лишней волокиты можно написать "на месте", а не дублировать (! один из важных принципов "чистого кода"). То есть Вы получаете ошибку в XMLLoader, и сообщаете о ней наружу. Снаружи получают ошибку (которую УЖЕ получили в XMLLoader) и обрабатывают по-новой.
Единственное "оправдание" всей этой IT-телефонии — желание сделать красивый ООП с ответственными объектами с говорящими именами и т.д. А родные классы слишком уж абстрактны — фиг знает, что грузит этот мужик с размытым именем URLLoader))
Открою Вам один секрет, только Вы никому не говорите! ;) URLLoader не финальный.

ramshteks
29.04.2012, 09:32
проверка валидности в момент получения, а не в момент доступа. Событие о завершении не будет, если хмл не валидна
А я разве сказал, что я его обернул, а не переопределил? ;)

Wolsh
29.04.2012, 11:46
Нет, не сказали. Это следует из фраз об "общем коде XMLLoadera" и "ряде очень удобных функций".
А я говорил о том, что можно "переименовать" класс, ну может добавить сахарку, если уж очень хочется.
Но удлинять цепи нет смысла.
Событие COMPLETE -> проверка на ошибку при создании объекта XML -> обработка ошибки: послать событие "загрузка завершена без ошибки" или "загрузка завершена с ошибкой".
Теперь смотрим, что происходит снаружи. Получаем либо аналог события COMPLETE (но с гарантией что в data лежит валидный XML), либо аналог ошибки, подразумевающий подспудно что была какая-то загрузка и загрузилось что-то не то, но тем не менее загрузка завершилась и ждать события COMPLETE нет смысла.
Я не вижу никаких преимуществ в этой тавтологии. Мне кажется гораздо логичней и упорядочней получить событие о том, что процесс загрузки завершился, и в обработчике определить, валидный это документ или нет. Мне не нравится идея добавлять к загрузчику документа лишнюю ответственность, не связанную с задачей загрузки. Это не его ума дело. Может я захочу рассмотреть загруженные байты, преобразовать их в строку и починить XML; или получить валидный фрагмент из невалидной XMLки, а не тупо завернуться в простыню и ползти на кладбище. Приложение вовсе не обязано тотально ломаться из-за ошибок внешнего контента, или из-за того что RSS оказался не в той кодировке — по сути абсолютно валидный, если правильно прочитать символы значений узлов.
И тут встает главный вопрос абстрагирования — если задача загрузчика только загрузить документ, то нафига его вообще называть "XMLLoader"? Ведь грузить он может что угодно.
Но всё это конечно моё имхо, просто поразмышлять лишний раз. Делайте как Вам удобно.