来自HTTPService的ArrayCollection在调用后更新,并且不更新视图

时间:2021-12-20 20:55:42

I have created a simple method to retrieve XML output from an HTTPService and populate a database from it, but due to the async nature of Flex, the functions go through while its still retrieving data - hence causing the function to return a null value. Please find code below;

我创建了一个简单的方法来从HTTPService检索XML输出并从中填充数据库,但由于Flex的异步性质,函数在仍然检索数据时会通过 - 因此导致函数返回空值。请在下面找到代码;

View: Declarations

查看:声明

<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:dao="database.*"
    preinitialize="open_databaseConnection();"
    creationComplete="init();" 
    title="Indexes">
<fx:Declarations>
    <dao:IndexesDAO id="srv"/>
</fx:Declarations>

View Functions

查看功能

private function open_databaseConnection() : void {
     indexArrayCollection = new ArrayCollection;
     indexArrayCollection = srv.listIndexes();
}

database.IndexesDAO

database.IndexesDAO

package database {

import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;

import models.Index;

import mx.collections.ArrayCollection;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;
import mx.utils.ArrayUtil;
import mx.utils.ObjectProxy;

public class IndexesDAO {

    private static var _sqlConnection:SQLConnection;    
    private var SubSonic:HTTPService = new HTTPService;

    public function get sqlConnection() : SQLConnection {
        if (_sqlConnection) return _sqlConnection;

        var file:File = File.applicationStorageDirectory.resolvePath("db.db");
        var fileExists:Boolean = file.exists;
        _sqlConnection = new SQLConnection();
        _sqlConnection.open(file);

        if (!fileExists) {
            createDatabase();
            get_indexesXML(); //Calls populate database on result event.
        }

        return _sqlConnection;
    }

    protected function createDatabase() : void {
        var sql:String = 
            "CREATE TABLE IF NOT EXISTS indexes ( "+
            "id VARCHAR(200) PRIMARY KEY, " +
            "name VARCHAR(200))";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.execute();         
    }

    protected function get_indexesXML() : void {
        var requestString:String;

        requestString = "/rest/index.xml";

        var requestURL:String = Settings.ServerURL + requestString;

        SubSonic.addEventListener(ResultEvent.RESULT, populateDatabase);

        auth_send(requestURL);
    }

    private function auth_send(requestURL:String): void {   

        SubSonic.url = requestURL;
        SubSonic.headers = {Authorization:"Basic " + Settings.EncryptedCreds()};

        SubSonic.send();
    }

    protected function populateDatabase(evt:ResultEvent) : void {

        var indexArrayCollection:ArrayCollection = new ArrayCollection();

        var length:int;
        var i:int;

        length = (evt.result['server-response'].indexes.index.source.length);

        for (i = 0; i < length; i++) {


            var addArray:ArrayCollection;
            if (evt.result['server-response'].indexes.index[i].artist is ArrayCollection) {
                addArray = evt.result['subsonic-response'].indexes.index[i].artist;
            } else if (evt.result['server-response'].indexes.index[i].artist is ObjectProxy) {
                addArray = new ArrayCollection(ArrayUtil.toArray(evt.result['server-response'].indexes.index[i].artist));
            }

            indexArrayCollection.addAll(addArray);
        }

        var IndexesDAO:IndexesDAO = new IndexesDAO();

        for each (var indexArr:Object in indexArrayCollection) {
            var index:Index = new Index();
            index.id = indexArr.id;
            index.name = indexArr.name;
            IndexesDAO.create(index);
        }           
    }

    public function create(index:Index) : void {
        var sql:String = "INSERT INTO indexes (id, name) VALUES (?,?)";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.parameters[0] = index.id;
        stmt.parameters[1] = index.name;
        stmt.execute();
    }

    public function listIndexes() : ArrayCollection {           
        var sql:String = "SELECT * FROM indexes ORDER BY name";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.execute();
        var result:Array = stmt.getResult().data;
        if (result)
        {
            var list:ArrayCollection = new ArrayCollection();
            for (var i:int=0; i<result.length; i++) {
                list.addItem(result[i]);    
            }
            return list;
        }
        else
        {
            return null;
        }

    }

    public function refreshIndexes() : ArrayCollection {
        var sql:String = "DROP TABLE indexes";
        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = sqlConnection;
        stmt.text = sql;
        stmt.execute();

        return listIndexes();
    }

}
}

As you can see the view calls listIndexes();

正如您所见,视图调用listIndexes();

But it can go through the database population before it can retrieve the result from HTTPService hence producing a null result. Any ideas on how to fix this?

但它可以通过数据库填充,然后才能从HTTPService检索结果,从而产生null结果。有想法该怎么解决这个吗?

1 个解决方案

#1


1  

you may want to dispatch an event at the end of populateDatabase and run the

您可能希望在populateDatabase的末尾分派一个事件并运行

indexArrayCollection = srv.listIndexes();

part in the eventlistener. then you can be sure that the results are already loaded.

参与eventlistener。那么你可以确定结果已经加载了。

private function open_databaseConnection() : void {
     indexArrayCollection = new ArrayCollection;
     srv.addEventListener(MyCustomEvent.DATA_LOADED, onDataLoaded);
}

private function onDataLoaded(evt:MyCustomEvent):void
{
    indexArrayCollection = srv.listIndexes();
}

#1


1  

you may want to dispatch an event at the end of populateDatabase and run the

您可能希望在populateDatabase的末尾分派一个事件并运行

indexArrayCollection = srv.listIndexes();

part in the eventlistener. then you can be sure that the results are already loaded.

参与eventlistener。那么你可以确定结果已经加载了。

private function open_databaseConnection() : void {
     indexArrayCollection = new ArrayCollection;
     srv.addEventListener(MyCustomEvent.DATA_LOADED, onDataLoaded);
}

private function onDataLoaded(evt:MyCustomEvent):void
{
    indexArrayCollection = srv.listIndexes();
}