2011-08-25 82 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(); 
} 

錯誤處理和刪除/添加適當的事件。您也可以禁用搜索,直到最後一個完成,這與定時器結合不應侵入用戶。

相關問題