Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   MVC - как правильно сделать сигнал о загрузке XML? (http://www.flasher.ru/forum/showthread.php?t=146917)

Nemez 21.11.2010 22:09

MVC - как правильно сделать сигнал о загрузке XML?
 
Здравствуйте. Хочу сделать все не как всегда, а правильно. Итак, есть контроллер
Код AS1/AS2:

package 
{
        import flash.display.*;
        import flash.events.*;
        import flash.utils.*;
 
        public class Controller extends Sprite
        {
                public var view:View;
                public var xmlWohnungen;
 
 
 
                public function Controller()
                {
                        this.addEventListener(Event.ADDED_TO_STAGE,init);
 
                }
                private function init(event:Event):void
                {
                        view = new View;
                        this.addChild(view);
                        xmlWohnungen = new XMLLoader();
                }
 
        }
}

Есть View, оно все отображает,
и есть XMLLoader, он же парсер, из него пойдут данные в Модель :
Код AS1/AS2:

package 
{
        import flash.xml.*;
        import flash.events.*;
        import flash.net.*;
 
 
        public class XMLLoader
        {
                public var xmlDaten:XML;
                public var xmlDateiDaten:URLLoader;
                public var myURLRequest:URLRequest;
 
                public function XMLLoader()
                {
                        xmlDateiDaten = new URLLoader();
                        myURLRequest = new URLRequest();
                        myURLRequest.url = "data.xml";
                        xmlDateiDaten.load(myURLRequest);
 
                        xmlDateiDaten.addEventListener(Event.COMPLETE, weiter);
 
                }
                private function weiter(e:Event)
                {
                        xmlDaten = new XML(e.target.data);
                }                                               
        }
}

Задача такая, чтобы после загрузки XML подать сигнал в контроллер, что можно посылать информацию во View. Понимание такое, что надо написать dispatchEvent в XMLLoader и отловить его в контроллере. Вроде просто, но самому никак в первый раз не написать.
Помогите пожалуйста с dispatchEvent в XMLLoader и addEventListener в контроллере.
P.S: 1. Я знаю, что можно сделать проще и хитрее, но хочется сделать "по правилам".
2. Материалы по MVC на форуме читал, но не смог приспособить(угадал все буквы, но слово сложить не смог)

gloomyBrain 21.11.2010 22:18

1) контроллер наследуется от EventDispatcher
2) Контроллер создает себе View и Model (Model У Вас вообще не заметил)
3) Контроллер грузит данные (т.е. выполняет функции Вашего XMLLoader'а) и по окончании загрузки пихает их в Model
4) Model диспатчит евент при изменении данных (т.е. у нее срабатывает сеттер, в котором диспатчится событие)
5) View подписывается на события Model и обновляет себя когда нужно

PS
- у Veiw доступ к Model есть только на чтение
- у Controller доступ к Model и на запись, и на чтение
- у View есть ссылка на Model
- у Controller есть ссылки и геттеры для Model и View (так как он их создает)
- у Model нет ссылок ни на кого и она наследуется от EventDispatcher

Котяра 21.11.2010 22:26

XMLLOader - часть контроллера. после того какон загрузит xml пусть "парсит" её. Т.е. изменяет данные модели исходя их xml данных. Если виды подписаны на изменение модели - они всё отобразят.

Nemez 21.11.2010 22:43

Спасибо за ответ,
Цитата:

контроллер наследуется от EventDispatcher
тогда он не может быть главным классом(точкой входа в программу)?
Цитата:

Model диспатчит евент при изменении данных (т.е. у нее срабатывает сеттер, в котором диспатчится событие)
Вот с этим кодом я и просил помощи, если можно.

gloomyBrain 21.11.2010 22:57

Цитата:

тогда он не может быть главным классом
Получается, что нет. Ему и незачем =)

Ну, насчет кода - как-то так:
Код AS3:

package {
 
        import flash.display.Sprite;
        import flash.display.StageAlign;
        import flash.display.StageScaleMode;
        import flash.events.Event;
 
        /*
        * @author gloomyBrain
        */

 
        public class Main extends Sprite {
 
                private var _controller:Controller;
 
                public function Main():void {
                        if (super.stage) this.init();
                        else super.addEventListener(Event.ADDED_TO_STAGE, init);
                }
 
                private function init(event:Event = null):void {
                        super.removeEventListener(Event.ADDED_TO_STAGE, init);
                        super.stage.align = StageAlign.TOP_LEFT;
                        super.stage.scaleMode = StageScaleMode.NO_SCALE;
 
                        // entry point
 
                        _controller = new Controller();
 
                        super.addChild(_controller.view);
 
                        _controller.loadXML();
 
 
                }
 
        }
 
}

Код AS3:

package  {
 
        import flash.events.Event;
        import flash.events.EventDispatcher;
 
        /*
        * @author gloomyBrain
        */

 
        public class Controller extends EventDispatcher {
 
                private var _view:View;
                private var _model:Model;
 
                public function Controller() {
 
                        super();
 
                        _model = new Model();
                        _view = new View(_model);
 
                }
 
                public function loadXML():void {
 
                        // грузщим xml
 
                }
 
                private function onXMLComplete(event:Event):void {
 
                        // тут заполняем модель полученными данными
 
                        _model.data = ... ;
 
                }
 
                public function get view():View {
                        return _view;
                }
 
                public function get model():Model {
                        return _model;
                }
 
        }
 
}

Код AS3:

package {
 
        import flash.events.IEventDispatcher;
 
        /*
        * @author gloomyBrain
        */

 
        public interface IModel extends IEventDispatcher{
 
                function get data():Object;
 
        }
 
}


Код AS3:

package  {
 
        import flash.events.Event;
        import flash.events.EventDispatcher;
 
        /*
        * @author gloomyBrain
        */

 
        public class Model extends EventDispatcher implements IModel {
 
                private var _data:Object = null;
 
                public function Model() {
 
                        super();
 
                }
 
                public function get data():Object {
                        return _data;
                }
 
                public function set data(value:Object):void {
                        _data = value;
                        super.dispatchEvent(new Event(Event.CHANGE));
                }
 
        }
 
}

Код AS3:

package  {
 
        import flash.display.Sprite;
        import flash.events.Event;
 
        /*
        * @author gloomyBrain
        */

 
        public class View extends Sprite {
 
                private var _model:IModel; // интерфейс, т.к. доступ только на чтение
 
                public function View(model:IModel) {
 
                        super();
 
                        _model = model;
 
                        // слушаем изменения модели
                        _model.addEventListener(Event.CHANGE, redraw);
 
                }
 
                private function redraw(event:Event):void {
 
                        var newObject:Object = _model.data;
 
                        // здесь перерисовываемся
 
                }
 
        }
 
}


Nemez 22.11.2010 00:33

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

private var _model:IModel;
...                       
_model.addEventListener(Event.CHANGE, redraw);
 
private function redraw(event:Event):void {
 
    var newObject:Object = _model.data;                       
}

?

gloomyBrain 22.11.2010 00:46

Ну, по идее, если модель одна для всех View можно
а) обновлять эти View из родительской View
б) передавать в каждую View эту самую модель, и пусть они сами перерисовываются, как им угодно

Nemez 22.11.2010 01:06

Большое Вам спасибо.

Psycho Tiger 22.11.2010 17:14

Цитата:

1) контроллер наследуется от EventDispatcher
Он наследуется от того, кто реализует обсервер или вообще ни от чего.
Цитата:

2) Контроллер создает себе View и Model (Model У Вас вообще не заметил)
Не обязательно. Контроллер вправе получить модель извне - главное чтобы все связи были налажены и тройка была готова к работе.
Цитата:

3) Контроллер грузит данные (т.е. выполняет функции Вашего XMLLoader'а) и по окончании загрузки пихает их в Model
Не совсем контроллер - некий модуль, работающий в контроллере, но спорно: загрузкой вполне себе может заниматься и модель, тут уж каждый выбирает по удобствам.

P.S. начал писать super таки? =) Крутой.)

Nemez 22.11.2010 21:01

Цитата:

главное чтобы все связи были налажены
Простите за настырность, но как можно наладить связи, кроме как сажать одно в другое? Статик переменные, EventDispatcher? Как оно функционирует?


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

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