如何构造我的类以避免使用静态函数

时间:2011-11-16 12:07:50

标签: xml actionscript-3 class event-listener

我有一个Flash应用程序,可以创建一种powerpoint演示文稿 所有“幻灯片”都存储在XML文件中,可以读取和处理。

我正在尝试使用此XML文件构建演示文稿。

目前,我的主要课程有初始函数main和静态函数processXML
main使用名为initDB的函数启动我的database类。我的一个问题是initDB放弃了处理,因为它依赖于事件监听器。加载完XML文件后,事件监听器会在main上启动静态函数,以便从该文件创建对象。

问题是因为事件监听器继续处理(在不确定的时间之后),所以函数不再由main类控制。
通常情况下,在这种情况下,我会避免使用静态,因为我通过在处理时使用returns来控制主函数的处理 - 即一个返回值以将控制权拉回调用者类的函数。

现在,所有这些都产生了影响,我不能使用addChild调用,或者实际上任何类似的调用,因为函数是静态的。

如果你可以节省一些时间,我真的需要重新考虑我的文件的工作方式。

主要类

public static var databaseXML:XML;
public var database:ContentDatabase = new ContentDatabase();

public function main()
{
    database.initDB();
}

public static function processXML()
{
    //Get First Slide
    var introSlide:SlideLayout = new SlideLayout();
    var allSlides:XMLList = main.databaseXML.children();
    var introSlideXML:XML;
    for each (var slide:XML in allSlides)
    {
        introSlideXML = slide;
        break;
    }
    var theSlide:MovieClip = introSlide.createSlide(introSlideXML);
    addChild(theSlide); //Fails, Obviously
}

ContentDatabase类

private var xmlLoader:URLLoader;

public function initDB()
{
    xmlLoader = new URLLoader();
    xmlLoader.addEventListener(Event.COMPLETE, onComplete, false, 0, true);
    xmlLoader.addEventListener(IOErrorEvent.IO_ERROR, onIOError, false, 0, true);
    xmlLoader.load(new URLRequest("resources/slides.xml"));
}

private function onComplete(e:Event):void
{
    try
    {
        main.databaseXML = new XML(e.target.data);
        xmlLoader.removeEventListener(Event.COMPLETE, onComplete);
        xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
        main.processXML();
    }
    catch (err:Error)
    {
        trace('broke: ' + err.message);
    }
}
private function onIOError(e:IOErrorEvent):void
{
    trace('broke: ' + e.text);
}

我对所有关于如何构建这个项目的想法持开放态度,允许我进行这种沟通。

理想情况下,我希望ContentDatabase类只保留XML处理。

1 个答案:

答案 0 :(得分:2)

您的主要& ContentDatabase类过于紧张了!

您的数据包含在XML文件中,实际上您需要先加载文件,解析,整理和放置文件。存储数据,然后您可以操纵这些数据。

我不同意Sr.Richie,这里真的不需要Singleton。

ContentDatabase应该只关心加载XML,理想情况是源URL不应该在类中进行硬编码。

例如,您可以将url作为参数传递给initDb方法

     database.initDB("resources/slides.xml");

加载数据后,最佳做法是派遣一个事件通知Main类数据已准备就绪。您可以使用CustomEvent或使用Signal并将数据作为Object传递。这样,您就不会在Main和ContentDatabase类之间产生不必要的依赖关系。

    private function onComplete(e:Event):void
    {
        try
        {
            main.databaseXML = new XML(e.target.data);
            xmlLoader.removeEventListener(Event.COMPLETE, onComplete);
            xmlLoader.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);

            //better process the XML data here...
            processXML();

        }
        catch (err:Error)
        {
            trace('broke: ' + err.message);
        }
    }

    private function processXML():void
    {
         // process the data...
         // inform the Main class by dispatching an Event
         // and pass the data as a parameter
         // use a CustomEvent or a Signal
     }

然后在你的主类

     //If you use a CustomEvent
     private function xmlLoadComplete( event:XMLCustomEvent ):void
     {
         var introSlideXML:XML = event.introSlideXML;
         var theSlide:MovieClip = introSlide.createSlide(introSlideXML);  
     }

有几种方式可以发送和发送听主班和&之间的事件ContentDatabase。如上所述,您可以使用信号。您还可以通过将事件调度程序传递给ContentDatabase来创建轻度依赖关系。这样做是为了确保同一个调度程序监听和分派事件。

     public var database:ContentDatabase = new ContentDatabase(dispatcher);

然后在ContentDatabase contstructor中......

       this.dispatcher = dispatcher;

然后在processXML()

    private function processXML():void
    {
          // after all the processing
          dispatcher.dispatchEvent( new XMLCustomEvent (introSlideXML ) );
     }

当然还有你的主课程

   //In case of CustomEvent
   public function main()
   {
       //the same dispatcher listens
       dispatcher.addEventListener( XMLCustomEvent.XML_LOADED , 
                                        xmlLoadComplete );
       database.initDB();
   }

尽管可以使用XML作为本机AS3对象,但我通常更喜欢创建自己的Object或Class,使用XML数据填充它,以便我可以直接调用其属性,而不必查询XML ,但这是个人品味......