Зареждане на данни от XML файл и тяхната презентация във Flash MX
   FlashBG Форуми
Пример
Автор: Petyo и Boby Dimitrov | Последна промяна: 25.07.20023
Вижте готовия пример!    Свалете примера архивиран!
Описание
Този пример има за цел да представи основните положения при работа с Flash и външни източници на информация. В нашия случай става дума за списък с новини, всяка от които включва заглавие, снимка и кратък текст. Използваме Flash за изграждането на презентационната част, докато информацията се съхранява в външен XML файл, който от своя страна може да е генериран динамично от система за управление на съдържанието (CMS) например.

Употребата на XML като формат на данните, постъпващи във Flash е за предпочитане пред зареждането на променливи s LoadVariables, макар и по-бавна като изпълнение и ресурсоемка. Структурираната в XML формат информация позволява бързо и лесно обхождане и обработка. Тук можете да видите примерния XML файл, от който ще черпим данните за нашия блок с новини.
План за действие
Първа стъпка е да подготвим макет, по който да се визуализират новините. Този макет ще представлява един movie clip, в който ще поместим няколко placeholder елементи - в случая празни текстови полета и movie clip. В последствие ще запълним празните елементи с информацията, която ще заредим от XML файла. След като изработим макета, ще заредим XML файла, ще запълним елементите и ще размножим макета колкото пъти е нужно за да покажем всички новини, описани във XML файла, всичко това със ActionScript. За финал ще добавим и примерно скролиране, което ще ни позволи да четем всички новини, дори и да са много на брой.

Така изработения новинарски блок позволява ясно разграничаване между презентация и информация, между работата на дизайнера и програмиста. Това означава, че дизайнера може да изработи макета на новината без да зависи от програмиста, а той от своя страна може да състави ActionScript-a без да пречи на дизайнера. Освен това, веднъж имайки говотия ActionScript ще е много лесно да се промени визията на блокчето с новини без да се търси програмистка намеса.
Изготвяне на шаблона за единична новина
Елементите, изграждащи всяка новина в XML файла, са:
  • Заглавие на новината
  • Снимка
  • Дата на новината
  • Пълен текст на новината
На всеки от елементите трябва да съответства такъв във Flash. За целта ще създадем три текстови полета - по едно за текстовите данни - и едно празно movie clip за снимката. От ключово значение е именуването елементите във Flash, за да могат техните параметри да бъдат достъпни посредством ActionScript и при зареждането да се "напълнят" с подадената информация от XML файла. Ето нашето предложение:



Обърнете внимание на имената на елементите - след това ще ги откриете във завършения ActionScript.

След като приготвим визуално макета, трябва да настроим неговите Properties. Нужно е да е отметнато Еxport for ActionScript, за да можем посредством ActionScript да го манипулираме. В полете Indentifier въвеждаме NewsTemplate - това ще е името, с което ще се обръщаме към макета за новината. С това работата ни по макета на отделната новина е приключена.
Създаване на кода, обработващ XML файла
Извън обхвата на този пример е да се илюстрира изграждането на структурата на файла, от който ще теглим данните. Заслужава да се отбележи факта, че зареждането на XML файла става асинхронно, тоест обекта извиква "събитие", когато зареждането на файла прикючи.

Дискутирана е темата за неудобствата на Flash средата за писане на по-дълъг код в ActionScript панела - именно и за това набират популярност инструменти и plugins за различни текстови редактори, които да поддържат оцветяване и по възможност компилиране на Flash файла. Личният ни фаворит си остава малкият, бърз и безплатен sciteflash. Стъпка напред в отделянето на програмирането от дизайна е цялостното изнасяне на кода в външни .as (или .mx) файлове. Директивата #include позволява зареждането на външни скриптови файлове. при компилирането. Това позволява целият код да бъде изнесен във отделен файл. В случая, за простота на примера, сме избегнали този похват и сме поместили кода в първия кадър от Flash файла. Следва неговото съдържание, а по-долу е анализа на самия ActionScript.

// Създаваме XML обект Receiver = new XML(); Receiver.ignoreWhite = true; // Игнорира паузите и новите редове във XML файла Receiver.onLoad = function (success) // Изпълнява се след като XML файла бъде зареден { var Row; // Will get popped on the iteration loop var i = 0; // Временна променлива var m; // Временен указател към movie clip // Проверяваме дали зареждането е успешно; ако не е - показваме съобщение за грешка if (!success) return trace("Failed Loading Xml File"); // Създаваме контейнер, в който ще подреждаме размножения макет на новината _root.createEmptyMovieClip("NewsContainer", 1); while (Row = this.firstChild.firstChild) { // Прикачваме макета _root.NewsContainer.attachMovie("NewsTemplate", "NewsTemplate" + ++i, i); m = _root.NewsContainer["NewsTemplate" + i]; // Временен указател // Вкарваме данните от XML файла в макета m.Title.text = Row.attributes.title; m.Date.text = Row.attributes.date; m.Content.text = Row.childNodes.join(""); m.Content.autoSize = true;// Кара текстовото поле да се разтяга според съдържанието m.pic.loadMovie(Row.attributes.pic); // Зареждаме снимката // Позиционираме макета под предишния m._y = _root.NewsContainer["NewsTemplate" + (i - 1)]._y + _root.NewsContainer["NewsTemplate" + (i - 1)]._height; // Премахваме първия ред от данните от XML файла - вече сме го обработили this.firstChild.firstChild.removeNode(); }// end while // Това ще позволи скролиране на целия лист новини в зависимост от положението на курсора // Примерно решение, използва се само за пълнота - не е изпробвано NewsContainer.onEnterFrame = function () { this._y += Math.abs(Stage.height/2 - _root._ymouse) > 50 // Ако курсора е в средата на прозореца - не правим нищо ? (Stage.height/2 - _root._ymouse)/5 : 0; // Спираме скролирането, ако списъка е стигнал до края си this._y = this._y > 0 ? 0 : this._y < -this._height ? -this._height : this._y; } } Receiver.load('data.xml');

Анализ на кода, обработващ XML файла

Receiver = new XML(); Receiver.ignoreWhite = true; // Игнорира паузите и новите редове във XML файла

Създаваме нов обект от клас XML - за всеки, който е упражнявал обектно ориентирано програмиране, горната конструкция изглежда познато. Трябва да се вземе предвид ignoreWhite стойността, в противен случай интервалите и новите редове биват третирани като възли. Следва дефиницията на функцията, която ще бъде изпълнена при зареждането:

Receiver.onLoad = function (success) { ... }

След това декларираме няколко променливи и правим проверка дали XML файла е зареден. Aко не е - показваме съобщение за грешка; възможно е да замените съобщението със ваш код за управление на грешката:

if (!success) return trace("Failed Loading Xml File");

Създаваме на сцената нов празен movie clip с име "NewsContainer" в ниво 1, в който после ще подреждаме размножените макети на новината:

_root.createEmptyMovieClip("NewsContainer", 1);

Със следващия цикъл обхождаме всички елементи от поредната новина. Вариaции за това как точно да обходим елементите от масива има много, но в случая - тъй като винаги оперираме с данните само от текущия node - подобна обработка спестява "слизането" чрез this.childNodes[0].childNodes[i], което би се получило, ако използвахме for вместо while.

while (Row = this.firstChild.firstChild) { ... this.firstChild.firstChild.removeNode(); }

Във всяко завъртане на горния цикъл, в movie clip "NewsContainer" създаваме instance на "NewsTemplate" за всяка отделна новина в XML файла:

_root.NewsContainer.attachMovie("NewsTemplate", "NewsTemplate" + ++i, i);

Следва прикачване на всички данни към съответните текстови полета и снимката. Тук внимание заслужават следните два реда:

m.Content.text = Row.childNodes.join(""); m.Content.autoSize = true;// Кара текстовото поле да се разтяга според съдържанието

Първия ред създава низ от всички childNodes. Причината за това е възможността в текста да има други тагове, които желаем да бъдат част видими (да не забравяме и възможността на текстовото поле да поддържа ограничени форматиращи тагове - A, B, FONT, I, U с помощта на които може да се оформи rich text). Втория указва на текстовото поле със съдържанието на новината да се удължи в зависимост от дължината на текста. След като сме обработили цялата новина, спокойно можем да премахнем възела от XML обекта ни:

this.firstChild.firstChild.removeNode();

Позиционира макета на поредната новина под предишния, като отчитаме неговата позиция по Y и височината му:

m._y = _root.NewsContainer["NewsTemplate" + (i - 1)]._y + _root.NewsContainer["NewsTemplate" + (i - 1)]._height;

Заключение
След като цикъля while обходи всички новини, обработката на XML документа и визуализацията на новините са приключени. Ако всичко е минало както трябва, ще получим дълъг вертикален списък с новини и снимки. Нека да добавим и следното експериментално решение за навигацията:

NewsContainer.onEnterFrame = function () { this._y += Math.abs(Stage.height/2 - _root._ymouse) > 50 // Ако курсора е в средата на прозореца - не правим нищо ? (Stage.height/2 - _root._ymouse)/5 : 0; // Спираме скролирането, ако списъка е стигнал до края си this._y = this._y > 0 ? 0 : this._y < -this._height ? -this._height : this._y; }

Няма да дискутираме изпълението на подобен тип недружелюбно изглеждащ код - това е извън обхвата на примера. В крайна сметка целта е постигната - визуализация на информация от XML файл във Flash MX с помощта на XML обекта в ActionScript! Ако имате въпроси, не се колебайте да ги зададете на форумите ни! Пак там ще откриете и редица алтернативни решения на проблема за обработката на XML данните, които ще публикуваме с времето.