2015-02-15 1 views
2

Недавно я начал разбираться в пользовательских классах в AS3 (чтобы отточить мои привычки кодов лучшей практики) и хотел создать класс базы данных, который позволяет пользователю сначала создать экземпляр класса, который содержит всю информацию, необходимую для методов внутри класса для добавления, удаления, изменения (и т. д.) строк в таблице MySQL (через PHP). Конечно, это связано с использованием URLRequest, URLLoader и т. Д. Мой вопрос заключается в том, может ли кто-нибудь понять, как вернуть данные из метода, конкретно содержащего эти данные var, не полагаясь на метод, по существу отправляющий событие (тогда необходимо создать слушателя, а не встроить его в класс). Например,Использование пользовательского класса для обработки запросов к базам данных в AS3

var myDB:dataBase = new dataBase("dbase","table","username","pword"); 

//this creates an instance of a database class with methods like: 

trace(myDB.fetch(1)); //gets first row of table as a delimited string 

ИЛИ

if (myDB.delete(1)) {} 
//returns Boolean true if delete of row 1 was successful 

Я нашел ответ ниже, который содержал способ создать класс, который возвращает событие:

Combining URLRequest, URLLoader and Complete Event Listener In Actionscript 3.0?

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

package com.customClasses { 
    import flash.net.URLLoader; 
    import flash.net.URLRequest; 
    import flash.net.URLVariables; 
    import flash.net.URLLoaderDataFormat; 
    import flash.net.URLRequestMethod; 
    import fl.events.DataChangeEvent; 
    import flash.events.Event 

    public class dataBase { 
     public var dbs:String = ""; 
     public var usr:String = ""; 
     public var pwd:String = ""; 
     public var tab:String = ""; 
     var returnData:String = ""; 

    // Constructor 
    public function dataBase(dbs:String, usr:String, pwd:String, tab:String) { 
     this.dbs = dbs; 
     this.usr = usr; 
     this.pwd = pwd; 
     this.tab = tab; 
    } 

    public function fetch(idn:uint, par:String):String { 
     var returnData:String = "blank"; 
     var vUrlReq:URLRequest = new URLRequest ("dBase.php"); 
     var vUrlVars:URLVariables = new URLVariables(); 

     function onLoadVarsComplete(event:Event): void { 
      //retrieve success variable from our PHP script: 
      if(event.target.data.msg == "success") { 
       var rawData:URLVariables = new URLVariables(event.target.data); 
       returnData = rawData.fromPHP; 
      } else { 
       returnData = "failed!"; 
      } 
     } 
     vUrlReq.method = URLRequestMethod.POST;  
     vUrlVars.dir=dbs; // name of table affected 
     vUrlVars.alpha=usr; // username 
     vUrlVars.beta=pwd; // password 
     vUrlVars.dbase=tab; // name of table affected 
     vUrlVars.func="fetch"; // function for php script to use 
     vUrlVars.idnum=idn; //if >0 search for record with that id 
     vUrlReq.data = vUrlVars; 
     var vLoader:URLLoader = new URLLoader (vUrlReq); 
     vLoader.addEventListener("complete", onLoadVarsComplete); 
     vLoader.dataFormat = URLLoaderDataFormat.VARIABLES; 
     vLoader.load(vUrlReq); 

     return (returnData); 
    } 

returnData возвращается «пустой» ... так что я понимаю, мой метод не работает должным образом. Я также понимаю, что у меня есть некоторые проблемы с объемом строки returnData, и что я использую вложенную функцию (возможно, нет-нет). В противном случае, какие-то мысли?

+0

Конечно, вы получите «пустое», потому что вы забыли, что вам нужно ждать вашего «полного» события, которое запускается асинхронно. – akmozo

ответ

0

Чтобы сделать то, что вы хотите, вы можете использовать функцию обратного вызова или DataEvent слушателя, как это:

DB.as:

package { 

    import flash.net.*; 
    import flash.events.*; 

    public class DB extends EventDispatcher {  

     public static const DATA_LOADED = 'data_loaded'; 

     public function DB() { 
     } 

     public function getDataUsingDataEvent(file_path:String):void { 

      var url_loader:URLLoader = new URLLoader(); 
       url_loader.addEventListener(
        Event.COMPLETE, 
        function(e:Event):void 
        { 
         var event:DataEvent = new DataEvent(DATA_LOADED, true, false, url_loader.data); 
         dispatchEvent(event); 
        } 
       ) 
       url_loader.load(new URLRequest(file_path));  
     } 

     public function getDataUsingCallback(file_path:String, callback:Function):void { 

      var url_loader:URLLoader = new URLLoader(); 
       url_loader.addEventListener(
        Event.COMPLETE, 
        function(e:Event):void 
        { 
         callback(url_loader.data); 
        } 
       ) 
       url_loader.load(new URLRequest(file_path));  
     } 

    } 

} 

А потом:

var db:DB = new DB(); 

    db.addEventListener(
     DB.DATA_LOADED, 
     function(event:DataEvent):void { 
      trace(event.data); 
     } 
    ) 
    db.getDataUsingDataEvent('file_path'); 

    db.getDataUsingCallback(
     'file_path', 
     function(data:String):void { 
      trace(data); 
     } 
    ) 

Надеюсь, что это поможет.

0

Как вы уже сказали, это невозможно сделать в AS3. Вы не можете дождаться асинхронной операции (например, URLLoader/load()) перед возвратом функции и продолжением выполнения сценария.

Что вы можете сделать, если вы предпочитаете не использовать addEventListener() столько, это пройти через обратные вызовы или реализовать method chaining из promises. Эти шаблоны не обязательно лучше, чем использование событий, и имеют свои проблемы, но позволяют писать код, который, возможно, более читабельен как последовательность. Эти шаблоны распространены в Javascript (который имеет такое же асинхронное поведение, как ActionScript), например jQuery. Остерегайтесь "callback hell" и "поезда обломков". Эти методы направлены на то, чтобы сделать вещи проще писать, но иногда делают вещи более склонными к ошибкам.

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

  • Нет связанных вопросов^_^