2011-08-25 80 views
0

简单地理解问题,希望能为同样简单的解决方案:搜索功能投掷的错误#1009 - 空对象引用

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

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)使用数组,而不是ArrayCollection的(我发现有人谁发现这个地方工作了他们的项目在一些论坛)

4)添加定时器功能,试图限制多久分贝就会得到搜索。 (虽然我认为这是最好的解决办法,我想我会再次尝试这个)

注,发生了错误,从我可以告诉,这主要是由于输入搜索字符的结果太快

谢谢你的帮助。

回答

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对象作为一个参数,你没有laonger必须引用原始语句得到那个结果。

2.延迟

使用定时器,是的。但不要使用它来间隔进行数据库调用。你不知道什么时候停止接听这些电话,是吗?用它来检测用户是否仍在打字:当它比 - 比如 - 300ms更长时。对于一个KeyboardEvent.KEY_UP来接一个,然后将调用发送到数据库。一旦。

3.使用阈值

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

4.过滤的ArrayCollection

忽略所有上述的。一个更简单的解决方案可能是将要搜索的所有记录加载到ArrayCollection中,并使用filterFunction仅显示与特定字符串匹配的记录。只要这个集合不是巨大的(如成千上万的记录)并且实现起来更快,这种方法将会很好。

+0

感谢您的信息 - 很高兴知道正确的解决方案。 – SQLiteNoob

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

错误处理和删除/添加适当的事件。您也可以禁用搜索,直到最后一个完成,这与定时器结合不应侵入用户。

相关问题