2009-03-12 3 views
3

Мой вопрос очень прост: в flex3 есть способ загрузить файл xml синхронно?Flex 3: синхронная загрузка xml-файла

Я знаю, как загружать асинхронно, используя событие загрузки. Это может быть полезно, а может и нет. Я просто хочу прочитать файл, проанализировать его, сделать то, что я должен сделать с ним, и продолжить выполнение кода.

У меня есть компонент, который использует xml-файл для хранения некоторых параметров конфигурации. Мне нужно прочитать файл, когда объект инициализирован. Однако с моделью событий я не могу контролировать, когда файл загружен, поэтому я должен написать код для «ожидания» для загрузки кода. Это просто смешно, или это я? Я хочу, чтобы такой код:

var foo:Foo = new Foo(); //This constructor should read the xml and initialize the object. 
foo.doSomething(); //When I call this method the xml must be already handled. 

Я могу обрабатывать файл XML на событии, и она отлично работает, но срабатывает событие после метода йоЗотеЬЫпда.

Надеюсь, я сам объяснил. Я думаю, это должно быть очень просто, но это сводит меня с ума. Я не хочу писать код, чтобы ждать события, если это действительно необходимо. Я чувствую, что все это должно быть только одна строка кода!

ответ

1

Невозможно загрузить синхронно, флеш-память построена для Интернета, и вы никогда не можете быть уверены, сколько времени займет звонок. Воздух отличается тем, что он загружается из файловой системы, и там не существует такой же задержки.

Самое чистое решение - прослушивать загрузку внутри Foo и вызывать doSomething() изнутри, таким образом ваш «внешний» класс вообще не должен беспокоить.

Если вам действительно нужно вызвать foo.doSomething() извне, вы можете использовать систему событий.Пусть ваш класс Foo диспетчерская событие, когда это делается загрузка:

dispatchEvent(new Event(Event.COMPLETE, true)); 

Для того, чтобы поймать, что вам нужно будет слушать его, как так:

foo.addEventListener(Event.COMPLETE, handleFooComplete); 

И функция обработчик события должен выглядеть следующим образом:

private function handleFooComplete(e:Event):void{ 
    foo.doSomething(); 
} 

Однако вы решите это сделать, вам нужно будет слушать Event.COMPLETE на погрузчике. Там не обойтись.

1

Я думаю, что есть «после» с загрузкой.

так что вы должны разделить вызов на новый() и призыв к делать() в двух различных методов, поэтому новый() вызывается в initalisation и делать() является calld после загрузки()

pseudosyntax:

beforeInitialisation() 
    disableDoSomething() 
    new()... 
    loader.addEvent(AFTERLOAD, afterLoad) 


afterLoad() 
    enableDoSomething() 


someMethod() 
    doSomething() 
+0

Извините, я не понимаю. Внутри класса Foo я могу разделить код на разные события. Проблема в том, что я не могу контролировать, когда происходят события. foo.doSomething() следует вызывать после всех этих событий, и я не знаю, как это сделать. – rgargente

+0

«var foo: Foo = new Foo();» - часть и «foo.doSomething();» - часть должна быть в двух разных функциях/методах (в SQL это было бы ПЕРВОЙ и ПОСЛЕ-триггер) –

+0

Спасибо, Питер, теперь яснее. Тем не менее, это не соответствует моим потребностям, извините. Я не могу позволить себе позвонить кому-нибудь и просто ничего не делать. См. Мой собственный ответ – rgargente

0

Вызов foo.doSomething(); внутри обработчика событий для события XML загрузки (например, EVENT.Complete или сконвертировано в зависимости от того, как именно вы загружаете файл). Это рекомендуемый способ.

+0

Да, но это будет беспорядок. doSomething не является частью инициализации концептуально. Он будет вызываться много раз в течение жизненного цикла объекта. Прямо сейчас я могу назвать это сразу после init, если это абсолютно необходимо. Однако нет никаких оснований делать это отдельно от этого. – rgargente

+0

«Много раз» должен иметь предшественник. Попытайтесь определить это и создать и событие и установить doSomething() в качестве обработчика. – dirkgently

+0

Да, это так. Пользователь нажимает кнопку, которая запускает событие. В данный момент объект лениво создается при первом нажатии пользователем. Я буду инициализировать его при загрузке приложения. См. Мой новый ответ. Спасибо за вашу помощь! – rgargente

1

Я отвечу сам на себя, однако мне все равно хотелось бы знать, если кто-то придумает лучшие идеи. Ответы от dirkgently и Peter Miehle полезны, но не решают мою актуальную проблему.

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

Что мне нужно сделать, это загрузить файл xml перед созданием объекта и передать его как параметр конструктору. Таким образом, я убеждаюсь, что объект имеет xml-файл, загруженный, когда это необходимо. Это, однако, также не идеальное решение, потому что теперь я должен сделать другой класс ответственным за «частные вещи» Foo.

Любые лучшие идеи?

+0

«Замораживание приложения» - это точная причина, по которой заблокированный ввод-вывод не разрешен. – dirkgently

+0

AIR однако имеет объект FileStream с возможностью работы в синхронном режиме. – dirkgently

+0

Вы загружаете файл из сети? Если нет, то ждать не должно быть так долго. В противном случае, если это огромный файл, попробуйте использовать Socket/XMLSocket и прочитайте фрагменты. – dirkgently

1

Старый вопрос, но я уверен, что многие люди все еще приходят сюда, вот мое решение.

Создание пользовательского события, которое вы посылаете внутри функции, которая обрабатывает ResultEvent

Have объекта, который вы хотите сделать что-то, я думаю, что в данном случае это было Foo, чтобы слушать для этого пользовательского события, которое затем будет вызов doSomething().

Смежные вопросы