搜索函数抛出错误#1009 - 空对象引用

时间:2011-08-25 18:58:40

标签: flex sqlite

简单易懂的问题,希望能有类似的简单解决方案:

当我输入我的搜索查询时,我有时会在dataField = new ArrayCollection(result.data);行上收到“错误#1009无法访问空对象引用的属性或方法”。

AS3:

        private function getSearch():void
        {
            //status = "Loading data";
            selectStmt = new SQLStatement();
            selectStmt.sqlConnection = conn;
            var sql:String = "SELECT [Index], Title, CAST(Picture AS ByteArray) AS Picture FROM Data WHERE Title LIKE @searchTarget";
            selectStmt.parameters["@searchTarget"] = "%" + searchTarget + "%";  
            selectStmt.text = sql;
            selectStmt.addEventListener(SQLEvent.RESULT, selectResult2);
            selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError);
            selectStmt.execute();
            targetRecordId = pngIndex;
        }

        private function selectResult2(event:SQLEvent):void
        {
            //status = "Data loaded";

            selectStmt.removeEventListener(SQLEvent.RESULT, selectResult);
            selectStmt.removeEventListener(SQLErrorEvent.ERROR, selectError);

            var result:SQLResult = selectStmt.getResult(); 

            dataField = new ArrayCollection(result.data);

            if (result.data != null) {
                pngIndex = result.data.Index;
                pngTitle = result.data.Title;
                pngByteArray = result.data.Picture;
                targetRecordId = pngIndex;
            }
        }

MXML:

<s:List id="myList" 
        x="0" y="40" 
        width="100%" height="100%" 
        labelField="Title" 
        dataProvider="{dataField}"
        change="myList_changeHandler(event)"
        >   
</s:List>

我尝试过的事情(包括这些解决方案的排列):

1)在SelectResult2方法中移动错误代码

2)添加if (result.data == null)方法

3)使用Array而不是ArrayCollection(我发现有人发现这在某个论坛的某个地方适用于他们的项目)

4)添加计时器功能以尝试限制数据库搜索的频率。 (虽然我认为这是最好的解决方案,但我想我必须再试一次)

请注意,从我所知道的错误发生,主要是因为过快地输入搜索字符

感谢您的帮助。

2 个答案:

答案 0 :(得分:0)

首先,怎么样

if(result == null)
     return;

此外,计时器是一个好主意,通常大约半秒钟,这样就可以在用户输入时对您的数据库进行锤击。

private var timer:Timer = new Timer(500, 1);
protected function textChangeHandler():void{
     timer.reset();
     timer.addEventListener(TimerEvent.Timer, getSearch);//Could be moved to a creation complete
     timer.start();
}

错误处理并根据需要删除/添加事件。您也可以禁用搜索,直到最后一个完成,这与计时器一起不应该侵扰用户。

答案 1 :(得分:0)

<强> 1。使用响应者

您对数据库的每次调用都使用相同的事件处理函数。因此,当函数执行时,它可能已经丢失了对其原始语句的引用(因为在此期间启动了新的调用)。这就是为什么你在结果对象上得到那些无效点。

所以抛弃事件监听器并改为使用Responder,如下所示:

        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = connection;
        stmt.text = query;

        var resp:Responder = new Responder(onResult, onFail);
        stmt.execute(-1, resp);

'onResult'函数将SQLResult对象作为单个参数,您不再需要引用原始语句来获得该结果。

<强> 2。延迟

使用计时器,是的。但是不要用它来间隔进行数据库调用。你不知道什么时候停止拨打这些电话,对吗?用它来检测用户是否还在打字:当它需要的时间超过 - 例如 - 300毫秒。对于一个KeyboardEvent.KEY_UP来到另一个,然后激活对数据库的调用。一次。

第3。使用阈值

不要只用一个字母开始查询。使用至少2-3个字符的阈值。无论如何,你不会得到任何一个字符的相关建议。阈值应该高多少,取决于要搜索的集合的大小。

<强> 4。过滤ArrayCollection

忽略以上所有内容。更简单的解决方案可能是将您要搜索的所有记录加载到ArrayCollection中,并使用filterFunction仅显示与某个String匹配的记录。只要集合不是巨大的(如成千上万条记录),这种方法就可以了,并且实现起来更快。