Опубликован: 07.11.2006 | Уровень: специалист | Доступ: платный
Лекция 6:

Движемся дальше

Локальное сохранение XML

Одной из прекрасных возможностей, связанных с общими объектами, является возможность сохранять внутри них любые данные. Благодаря этому можно не импортировать каждый раз XML, содержащий имена файлов изображений, а сохранить массив рисунков локально. Мы также можем установить срок обновления для общего объекта, после которого будет выполняться повторный импорт XML в случае его изменения.

Методология этого подхода очень проста. Перед импортом XML с помощью sharedObject.getLocal мы проверяем, создан ли общий объект для фильма. Если не создан, или общий объект является более старшим, чем определенная дата, мы продолжим работу и импортируем XML. После импорта и обработки XML мы будем сохранять массив pictureObjects и текущее время в общем объекте. Если у нас уже есть общий объект, мы получим массив pictureObjects из общего объекта, а не из XML.

  1. Сначала создадим функцию для сохранения массива в общем объекте. Мы добавим вызов этой функции после успешной загрузки XML, а также уберем комментарий со строки кода для удаления statusClip.
    function parseMe(success) {
            if (success) {
                var pictures = this.firstChild.childNodes;
                for (var i = 0; i<piсtures.length; i++) {
                    var obj = {};
                    for (var j in pictures[i].attributes) {
                        obj [j] = pictures [i] .attributes [j];
                    }
                    pictureObjects.push(obj);
                }
                _root.refreshSharedObj();
                clearlnterval (this.updater);
                statusClip.removeMovieClip();
                _root.pictureDataComplete ();
            } else {
                _root.statusClip.statusText.text = "FAILED TO LOAD DATA";
                clearlnterval(this.updater);
            }
        }
  2. В функции refreshSharedObj нам нужно сначала получить общий объект с помощью sharedObject.getLocal. Затем мы поместим наш массив pictureObjects в общий объект.
    mySharedObj = sharedobject.getLocal("denim");
        mySharedObj.data.pictureObjects = pictureObjects;
  3. Затем нам нужно создать дату. Для этого можно использовать метод getTime объекта Date. Этот метод возвращает число миллисекунд, прошедших с 1 января 1970 года, что дает значение, с которым мы будем работать. Для этого сначала создаем новый инстанс объекта Date, а затем вызываем его метод getTime, сохраняя значение в качестве timeStamp в общем объекте.
    var dat = new Date();
        mySharedObj.data.timeStamp = dat.getTime();
  4. Окончательная функция включает весь код из шагов 2 и 3 плюс метод flush общего объекта для сохранения информации. Расположите функцию refreshSharedObj под функцией parseMe.
    function refreshsharedobj() {
            mySharedObj = sharedobject.getLocal("denim");
            mySharedObj.data.pictureObjects = pictureObjects;
            var dat = new Date();
            // store the timestamp in the shared object
            mySharedObj.data.timeStamp = dat.getTime();
            mySharedObj.flush();
        }
  5. Следующая функция - checkShared. Мы будем вызывать эту функцию из функции init и использовать возвращаемое значение функции для определения того, вызываем или нет функцию importXml. Если функция возвращает значение "истина", это будет означать, что данные были найдены в общем объекте, и нам не требуется импортировать XML; если же возвращается значение "ложь", приступаем к импорту XML. Наша функция лишь возвращает значение "истина", если она находит общий объект с массивом рисунков внутри него, а разница между текущим временем и временем его создания меньше определенного значения. Вот как сейчас примерно будет выглядеть наша функция init.
    function init() {
            // if the checkshared function returns true
            if (!checkshared()) {
                importXml();
            }
        }
  6. Первое, что нужно сделать в checkShared (это будет под функцией refreshSharedObj ), это получить общий объект.
    function checkshared() {
            mySharedObj = sharedobject.getLocal("denim");
        }
  7. Затем мы проверяем, содержит ли mySharedObj массив с именем pictureObjects в объекте data.
    function checkshared() {
            mySharedObj = sharedobject.getLocal("denim");
            if (mySharedObj.data.pictureObjects) {
            . . .
            }
        }
  8. Если это так, то мы сразу получаем нужные нам данные, и нам требуется просто проверить даты, поэтому мы создаем объект new Date.
    function checkshared() {
            mySharedObj = sharedobject.getLocal("denim");
            if (mySharedObj.data.pictureObjects) {
                var dat = new Date();
            }
        }
  9. Для сравнения текущей даты с датой сохранения общего объекта мы можем сделать следующее.
    dat.getTime () -mysharedObj.data.timeStamp;

    Это определит количество миллисекунд между текущим моментом и моментом установки общего объекта. Наилучший период для новой загрузки XML - примерно раз в неделю, поэтому мы проверяем, что значение меньше, чем 1000*60*60*27*7 = 604800000.

    Если оно меньше, возвращается "истина", если нет, ничего не будет возвращено. Мы так же вызываем функцию pictureDataComplete, которую создали к моменту окончания загрузки XML. Новый код выделен жирным шрифтом.

    function checkShared() {
            mySharedObj = sharedobject.getLocal("denim");
            if (mySharedObj.data.pictureObjects) {
                var dat = new Date();
                if (dat.getTime()-mysharedObj.data.timeStamp<604800000) {
              // retrieve the array from the sharedObject
                    _root.pictureObjects = mySharedObj.data.pictureObjects;
                    pictureDataComplete();
                    return true;
                }
            }
        }

    Приведем окончательный код.

    #include "tweento.as"
        #include "brightness.as"
        #include "stage.as"
        _root.filename = "pictures .xml";
        embedder._visible = 0;
        statusTf = new TextFormat("Arial", 40, 0x4375A6);
        statusTf.align = "center";
        statusTf.leading = -5;
        function createStatusMovie(tex) {
            _root.createEmptyMovieClip("statusClip", 1);
            statusClip.createTextField("statusText", 1, 0, 0, 550, 100);
            statusClip.statusText.embedFonts = true;
            statusClip. statusText. selectable = false;
            statusClip.statusText.setNewTextFormat(statusTf);
            statusClip.statusText.text = tex;
            statusClip._x = 0;
            statusClip._y = (Stage. original Height- statusClip.statusText.textHeight)/2-50;
        }
        function importXml() {
            trace("data imported from xml");
            pictureObjects = [];
            myXml = new XML();
            myXml.ignoreWhite = true;
            myXml.updateXmlStatus = function() {
                var percent = Math.round(this.getBytesLoaded()/ this.getBytesTotal()*100);
                if (percent<=0) {
                    percent = "0";
                }
                _root.statusClip.statusText.text = "PICTURE DATA LOADING \n"+percent+"%" ;
            };
            myXml.updater = setInterval(myXml, "updateXmlStatus", 20);
            myXml.onLoad = parseMe;
            myXml.load(_root.filename);
            _root.createStatusMovie("PICTURE  DATA  LOADING");
        }
        function parseMe(success) {
            if (success) {
                var pictures = this.firstChild.childNodes;
                for (var i = 0; i<pictures. length; i++) {
                    var obj = {};
                    for (var j in pictures[i] .attributes) {
                        obj[j] = pictures [i] .attributes [j];
                    }
                    pictureObjects.push(obj);
                }
                _root.refreshSharedObj();
                clearInterval(this.updater);
                statusClip.removeMovieClip();
                _root.pictureDataComplete();
            } else {
                _root.statusClip.statusText.text = "FAILED TO LOAD DATA";
                clearInterval(this.updater);
            }
        }
        function refreshSharedObj() {
            mySharedObj = sharedobject.getLocal("denim");
            mySharedObj.data.pictureObjects = pictureObjects;
            var dat = new Date();
            mySharedObj.data.timestamp = dat.getTime();
            mySharedObj.flush();
        }
        function checkShared() {
            mySharedObj = sharedobject.getLocal("denim" );
            if (mySharedObj.data.pictureObjects) {
                var dat = new Date();
                if (dat.getTime()-mysharedObj.data.timeStamp<604800000) {
                    trace("data found in shared object");
                    _root.pictureObjects = mySharedObj.data.pictureObj ects;
                    pictureDataComplete();
                    return true;
                }
            }
        }
        function pictureDataComplete() {
            trace("picture data loaded");
        }
        function init() {
            importXml();
        }
        function init() {
            if (!checkShared()) {
                importXml();
            }
        }
        init();
    Пример 5.11.
  10. Сохраните ваш файл под именем xmlInShared.fla и запустите его. Вот результат, который вы получите в окне Output.

    Мы добавили два выражения trace (выделены жирным шрифтом) для проверки того, откуда загружаются данные - из XML или из общего объекта. Можно поэкспериментировать с ними, чтобы понять, как они работают. Попробуйте изменить число миллисекунд даты окончания общего объекта. Таким же способом можно полностью удалить общий объект.

    function checkShared() {
            mySharedObj = sharedobject.getLocal("denim");
            // loop through properties and delete them
            for (var i in mySharedObj .data) {
                delete mySharedObj.data[i];
            }
        }

    В этом случае в окне Output отобразится, что данные были импортированы из XML.


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

Игорь Хан
Игорь Хан

у меня аналогичная ситуация. Однако, если взять пример из приложения (ball_motion_04_click for trial.fla) то след остается. при этом заметил, что в моем проекте в поле "One item in library" виден кружок, в то время как в приложенном примере такого кружка нет.

Вопрос знатокам, что не так?

Александр Коргапольцев
Александр Коргапольцев

объект созданый мной упорно не желает оставлять след(единственное что добился, так это то что шарик резво гоняется за курсором) функция duplicateMovieClip остаётся не активной, т.е. следа от объекта не остаётся, но если я тоже самый код вбиваю в учебный файл всё работает, не могу понять где я ошибаюсь и почему в документе созданном заново, не работает код начиная от функции duplicateMovieClip? 

Тамара Ионова
Тамара Ионова
Россия, Нижний Новгород, НГПУ, 2009
Магомед Алисултанов
Магомед Алисултанов
Россия, Волгоград, лицей 2