简体   繁体   中英

Using custom class to handle database inquiries in AS3

I recently started delving into custom classes in AS3 (to hone my best-practices coding habits), and wanted to create a database class that allows a user to first instantiate a class that contains all the information necessary for methods within the class to add, delete, modify (etc) rows in a MySQL table (via PHP). Of course, this involves using URLRequest, URLLoader and so forth. My question is whether anyone as figured a way how to return data from a method specifically containing that var data without relying upon the method essentially dispatching an event (then having to create a listener rather than having that built into the class). For example,

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

OR

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

I found the answer below that contained a way to create a class that returns an event:

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

but I want the method to return a string containing data from the database or a boolean confirmation, not to dispatch an event listener. Here is an example of the class I made:

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 returns "blank"... so I realize my method is not working as intended. I also realize there my be some scope issues with the returnData string, and that I am using a nested function (probably a no-no). Otherwise, any thoughts?

To do what you want, you can use a callback function or a DataEvent listener, like this :

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));     
        }

    }

}

And then :

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);
        }
    )

Hope that can help.

As you've stated it, this can't be done in AS3. You cannot wait for an asynchronous operation (such as URLLoader/load() ) before returning the function and continuing script execution.

What you can do, if you'd prefer not to use addEventListener() so much, is pass through callbacks, or implement method chaining of promises . These patterns are not necessarily better than using events, and have their own problems, but let you write code that is arguably more readable as a sequence. These patterns are common in Javascript (which has the same asynchronous behavior as ActionScript), for example jQuery. Beware of "callback hell" and "train wrecks". These techniques aim to make things simpler to write but sometimes make things more error prone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM