2

キャッシング付きの jQuery オートコンプリート リモート ソースを使用しています。jQuery UI Web サイトによるデモによると、キャッシング付きのリモート ソースの JavaScript は次のとおりです。

<script>
$(function() {
    var cache = {},
        lastXhr;
    $( "#birds" ).autocomplete({
        minLength: 2,
        source: function( request, response ) {
            var term = request.term;
            if ( term in cache ) {
                response( cache[ term ] );
                return;
            }

            lastXhr = $.getJSON( "search.php", request, function( data, status, xhr ) {
                cache[ term ] = data;
                if ( xhr === lastXhr ) {
                    response( data );
                }
            });
        }
    });
});
</script>

上記の JavaScript にコードを追加して、オートコンプリート リストに画像を表示します。http://jsfiddle.net/3zSMG/のような jQuery オートコンプリートで画像を表示するための優れた例がありますが 、キャッシュ部分は含まれていません。

私は試してみましたが、この例をキャッシング JavaScript を使用して既存のリモートに統合することはできませんでした。どんな助けでも大歓迎です。どうもありがとう。

フォローアップ: Andrew Whitaker の提案に従って、スクリプトを次のように更新しました。

<script>
$(function() {
    var cache = {},
        lastXhr;
    $( "#birds" ).autocomplete({
        minLength: 2,
        source: function( request, response ) {
            var term = request.term;
            if ( term in cache ) {
                response(cache[term]);
                return;
            }

            lastXhr = $.getJSON( "search.php", request, function( data, status, xhr ) {
                var results;
                if ( xhr === lastXhr ) {
                    results = $.map(data, function(item) {
                        return {
                        value: item.value,
                        avatar: item.avatar
                        };
                    });
                    cache[term] = results;
                    response(results);
                }                   
            });
        },
    }).data("autocomplete")._renderItem = function (ul, item) {
    if ( item.value != null ) {
        if ( item.avatar != null) {
            return $("<li/>")
                .data("item.autocomplete", item)
                .append("<a><img src='images/" + item.avatar + "' />" + item.value + "</a>")
                .appendTo(ul);
            }
        else {
            return $("<li/>")
                .data("item.autocomplete", item)
                .append("<a>" + item.value + "</a>")
                .appendTo(ul);
        }
    }
    }; 
});

そしてsearch.phpの内容:

<?php
require_once "config.php";
$term = trim(strip_tags($_GET['term']));//retrieve the search term that autocomplete sends
$qstring = "select id, subject as value, avatar from Suggests where subject LIKE '%".$term."%'";
$result = mysql_query($qstring);//query the database for entries containing the term
while ($row = mysql_fetch_array($result,MYSQL_ASSOC))//loop through the retrieved values
{
    $row['value']=htmlentities(stripslashes($row['value']));
    $row['id']=(int)$row['id'];
    $row['avatar']=$row['avatar'];
    $row_set[] = $row;//build an array
}
echo json_encode($row_set);//format the array into json data

?>

オートコンプリート リストで画像を表示できます。しかし、問題があります: いくつかの文字をキー入力した後、オートコンプリート リストが表示されます。さらにランダムな文字を追加し続けて、オートコンプリート リストが消えることを期待すると (ユーザー入力が一致しなくなったため)、そうではありません。アンドリューの例はうまくいきます。私のjavascriptに何か問題がありますか? Firebug でデバッグしようとすると、エラーが発生しました: TypeError 要素が null です。

エラー

4

2 に答える 2

3

デモの画像部分の鍵は、アイテムを提案するために生成される_renderItemを変更する関数をオーバーライドすることです。これは通常、ソースがand/orプロパティliを持つオブジェクトを含む配列であること、および内に画像を正しく表示できるようにするプロパティであることを意味します。labelvalue_renderItem

キャッシュ コードは、検索語と結果をハッシュに格納し、サーバーにアクセスする前にそのハッシュを調べます。

例としてリンクした JSFiddle を使用して、キャッシュと画像を行う StackOverflow の API を使用したものを次に示します。

$(document).ready(function() {
    var cache = {},
        lastXhr;

    $("#auto").autocomplete({
        source: function(request, response) {
            var term = request.term;

            if (term in cache) {
                response(cache[term]);
                return;
            }

            lastXhr = $.ajax({
                url: "http://api.stackoverflow.com/1.1/users",
                data: {
                    filter: request.term,
                    pagesize: 10
                },
                jsonp: "jsonp",
                dataType: "jsonp",
                success: function(data, status, xhr) {
                    var results;
                    if (xhr === lastXhr) {
                        results = $.map(data.users, function(el, index) {
                            return {
                                value: el.display_name,
                                avatar: "http://www.gravatar.com/avatar/" + el.email_hash
                            };
                        });

                        cache[term] = results;
                        response(results);                                 
                    }
                }
            });
        },
        delay: 500
    }).data("autocomplete")._renderItem = function(ul, item) {
        return $("<li />")
            .data("item.autocomplete", item)
            .append("<a><img src='" + item.avatar + "' />" + item.value + "</a>")
            .appendTo(ul);
    };
});​

:

  • この例は、jQueryUI の Web サイトの例よりも複雑です。これは、API からのデータを ( avatar/valueプロパティを持つように) 変換する必要があるためです。注意すべき重要なことは、呼び出しが結果の配列を変換した後に、受け取った値をキャッシュしていることです。$.map
  • これは複雑に見えますが、回答の上部にある 2 つのガイドラインを覚えておいてください。

例: http://jsfiddle.net/rK7TS/

于 2012-09-16T21:31:21.237 に答える
0

Here's what I did:

    lastXhr = $.getJSON( action, request, function( data, status, xhr ) {

        if( data && data !== null ) {
            var results;
            if( xhr === lastXhr ) {
                results = $.map(data, function(item) {
                    return {
                        value: item.value,
                        avatar: item.avatar
                    };
                });
                cache[term] = results;
                response(results);
            }
        } else {
            response([{ value: 'No results found.', avatar: null}]);
        }

    });
于 2014-10-12T15:27:37.357 に答える