Ошибка выдачи функции поиска # 1009 - ссылка на пустой объект - PullRequest
0 голосов
/ 25 августа 2011

Простая для понимания проблема в надежде на такое же простое решение:

Когда я набираю свой поисковый запрос, я иногда получаю «Ошибка # 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) Использование Array вместо ArrayCollection (я нашел кого-то, кто нашел, что это работает для их проекта на каком-то форуме)

4) Добавление функции таймера, чтобы попытаться ограничить частоту поиска в БД. (хотя я думаю, что это было лучшее решение, я думаю, мне придется попробовать это снова)

Обратите внимание, что, как я могу судить, возникает ошибка, в основном из-за слишком быстрого ввода символов поиска

Спасибо за вашу помощь.

Ответы [ 2 ]

0 голосов
/ 26 августа 2011

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 для отображения только тех записей, которые соответствуют определенной строке. Этот метод будет хорошо работать до тех пор, пока коллекция не будет гигантской (например, десятки тысяч записей) и будет быстрее внедряться.

0 голосов
/ 25 августа 2011

во-первых, как насчет

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

Ошибка обрабатывать и удалять / добавлять события в зависимости от ситуации.Вы также можете отключить поиск до завершения последнего, что в сочетании с таймером не должно быть навязчивым для пользователя.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...