3

dijit.form.FilteringSelectユーザーがリージョンを選択できるようにするために、 に裏打ちされたを使用dojox.data.QueryReadStoreしています (「オートコンプリート」メカニズムを考えてください)。ユーザーが文字を入力するたびにQueryReadStore、 はサーバーに要求を送信し、一致する領域の json リスト (関連付けられた ID を含む) を待ちます。十分に短いリストが表示されるまでに、ユーザーは目的の項目を選択します。[確かに、キーストロークごとにクエリを実行するのは最も効率的なパターンではありませんが、今のところは十分です。]

予期しない動作: まれではあるが特定の状況で、ユーザーが行った選択が「固執しない」場合があります。たとえば、ユーザーが「can」と入力すると、次の選択肢がこの順序で表示されます。

Atlantic Canada
Canada
English Canada
Lower Canada
Upper Canada
Western Canada

彼女がCanadaこれらの中から " " を選択した場合、dijit はドロップダウン選択を閉じ、彼女の選択を正しく選択します。しかし、ユーザーがフィールドを離れるまでに、選択は " " に切り替わりますAtlantic Canada!

その奇妙な現象は、少数の特定の地域で体系的に発生します。(最初は、行儀の悪い地域に共通する要因は、名前にアクセント付きの文字やハイフンが含まれていることだと思っていましたが、カナダの例では明らかにそうではありませんでした。これまでのところ、規則的なパターンを見つけることができませんでした。)

同様の問題についての言及はどこにも見つかりませんでした。私は喜んで調査しますが、私は道場に慣れていないので、道場のコードの内部を詳しく調べる前に、ポインタをいただければ幸いです。最初にどこを見ればよいでしょうか? その動作を引き起こす可能性のある問題は何ですか? 特定の仮説を除外できますか? この問題を解決するには、コンソール (または Firebug) をどのように使用すればよいですか? 等

この問題は、dojo 1.1.1 と dojo 1.2.3 の両方で発生します。

の(プログラムによる)生成は次のFilteringSelectとおりです。

new dijit.form.FilteringSelect({
   name = "region";
   autoComplete = false;
   hasDownArrow = false;
   labelAttr = "name";
   queryExpr = "${0}";
   store = new dojox.data.QueryReadStore({url:'/query/regions'});
}, myNode);

編集 (2009/02/18): 追加の詳細

ダメリンの答えに続いて、私FilteringSelectはこの状況をどう見たのか理解したいと思いました。ロギング関数をFilteringSelectのイベントonChangeとに接続するとonBlur、次のプレイバイプレイ シーケンスが得られます。

  • フィールドをクリックして、次のように入力します。can
  • 6 つのリージョン (上記) のドロップダウン リストが表示されます。
  • キーボード カーソルを使用して、リストを下の " Canada" (ID 1 の領域)に移動します。
  • を押しますEnter(したがって、ストアのアイテムを選択します)。ドロップダウン リストが消えて、テキスト " Canada" がフィールドに表示されます。この時点で、最初のイベントが発生し、次のログが記録されます。

    onChange event: region 1
    
  • を押してフィールドを離れtabます。ここでは、次の順序で 2 つのイベントが次々に発生します。

    onBlur event: region 1
    onChange event: region 246
    

(リージョン 246 はAtlantic Canadaです。) これは非常に興味深いことです... フィールド (onBlur) を離れるまでに、Canadaまだ選択された値です。謎の入れ替わりはその後…

4

6 に答える 6

2

私は今日同じ問題に遭遇し、Dojo バージョン 1.1.1 と 1.2.0 の両方に影響を与えました。

私の知る限り、ユーザーがフィールドを離れた後、FilteringSelect は最終的なクエリを実行し、クエリ結果に 1 つの結果のみが含まれていることを期待し、それをフィールドの値に使用します。

私にはバグのように見えますが (私が間違っていることが証明されていることを願っています)、今のところ問題があるかもしれません。

このページには、いくつかの (不完全な) 情報があります: http://www.nabble.com/Problems-with-QueryReadStore-td19269498.html

後で編集:

実際、重複するラベルがある場合は常に、その背後にあるデータストアに関係なく、FilteringSelect で同じ問題が発生します。

たとえば、ウィジェットがフォーカスを失うと、最初のオプションにリセットされます。

 <select id="coffee2" name="coffee2" 
    dojotype="dijit.form.FilteringSelect" 
    autoComplete="false">
    <script type="dojo/method" event="onChange"  args="newValue">
        console.log(dijit.byId('coffee2').getValue() + '/' + dijit.byId('coffee2').getDisplayedValue());
    </script>
    <option value="0">AAA</option>
    <option value="1">AAA</option>
    <option value="2">AAA</option>
    <option value="3">AAA</option>
    <option value="4">AAA</option>
  </select>

私の意見では、機能というよりもバグです。

于 2009-02-19T05:58:54.317 に答える
2

そのような行動の説明をようやく見つけたと思います。簡単に言うと、FilteringSelect が QueryReadStore に期待する契約の不履行が原因で発生します。また、QueryReadStore は json を生成するサーバー モジュールからの応答に完全に依存しているため、サーバーからの予期しない応答により契約を履行できませんでした。

私が理解したように、ユーザー入力の最後に、 FilteringSelect は Store (この場合は QueryReadStore) が、入力または選択された文字列と完全に一致する項目のみを返すことを期待しています。FilteringSelect は、Enter キーが押されたとき、またはユーザーがフィールドを離れたときに入力が終了したと見なします。この 2 つのイベントの前に、入力または選択されたテキストは単なるテキストです。現在、実際に選択されている項目はありません。

つまり、入力の最後で、FilteringSelect は、Store が何も選択されていない場合はゼロのアイテムを返し、選択されている必要があるアイテムを 1 つ返すことを期待します。したがって、地域のリストを提供すると、FilteringSelect はどれを選択するかを判断できず、最初の地域で停止します。

おっしゃるとおり、QueryReadStore はキーストロークごとにリクエストを送信します。この場合 (入力が終了する前)、FilteringSelect は Store がパターンに一致するアイテムを返すことを期待します。デフォルトのパターンは "enteredString * " で、アスタリスクは任意のシーケンスです。

2 つのケースを区別するために、QueryReadStore はリクエストをわずかに変更します。

  • キーストロークごとのサンプル リクエスト: /query/regions?name=enteredString*&start=0&count=5
  • 入力の最後のサンプル リクエスト: /query/regions?name=enteredString&start=0

ご覧のとおり、2 番目のリクエストでは、「enteredString」の末尾にアスタリスクがありません。このバリエーションは、サーバー側で正しい応答を構築するのに役立ちます。

うまく説明できたと思います。そうでない場合は、お気軽にお尋ねください。

于 2009-02-01T10:47:35.033 に答える
1

くそー、この特定の問題も私のお尻の本当の痛みでした!! そして、damelin answer のおかげで、これが私がそれを取り除く方法です。

私の場合、複雑なテーブルからの複数の db 値自体からの書式設定された文字列で埋められる必要がありました (いくつかの親と manyToMany 関係さえあります) dijit.form.filteringSelectdojox.data.QueryReadStore重複を避けるために、できるだけ早く db テーブルを分離するのが好きだと考えてください。これらはすべて、Zend Framework アプリケーションのコンテキスト内にあり、QueryReadStoreここで名前を付けるコントローラー アクションによって処理されますautocompletelistAction

したがって、ダメリンの回答から始めて、GETパラメーターとその最終的なアスタリスクを読み取り、autocompletelisteAction2つのリクエストのケースを分離する作業を開始しました。QueryReadStore

まず、パラメーターを消去し、最後の char を検索します。

$txt = (String) $this->_request->getParam('parameter');
$lastChar = substr($txt, -1);

次に、パラメーターに複数の文字があり、末尾にアスタリスクがない場合は、パラメーターを削除し$txtて、like 句を手動で作成します。

if ((strlen($txt) >= 1) && ($lastChar != '*')) {
  // here, the parameter is the full text, which the user selected by
  // clicking on a shown element of the filteringSelect

  // Therefore, I "explode" the parameter to correspond to my searched values
  // and I build my SQL LIKE clauses without "%"
  // Consequence? There is only one result which is the good one.
}
else {
  // here, the parameter is a "part" of the search, which the user typed in

  // Therefore, I build my SQL LIKE clauses with "%$txt%"
}
// Here I can just launch my SQL queries with the built LIKE clauses
// and return result(s) to the QueryReadStore

$txt複数の文字があるかどうかを確認するのはなぜですか? Zend Framework 内では、filteringSelect をページで「自動ロード」できる場合があり、完全に空の引数 (アスタリスクがなくても) が送信され、「展開」関数に送られます。

この複雑なシナリオは私のものですが、それぞれが正しい答えを提供するために、この単純な PHP テストをパラメーターに適応させることができると思います。

だから本当の仕事は道場の要素を通して理由を調査したので、ここでdamelinによって行われました.

于 2010-01-01T14:40:32.007 に答える
0

「ユーザーが文字を入力するたびに、QueryReadStore はサーバーにリクエストを送信します...」

設定できる FilteringSelect 属性 searchDelay があります。これは、要求を送信する前に、指定されたミリ秒数だけ待機します。

于 2009-11-11T14:51:34.353 に答える
0

これと同じ問題がありました。FilteringSelect.js の _setDisplayedValueAttr を変更して、すぐに戻るようにすることで解決しました。

_setDisplayedValueAttr: function(/*String*/ label, /*Boolean?*/ priorityChange){ return }

これは 1 日頭を悩ませた後です。この変更は明らかに非常に悪いことですが、私たちにとってはうまくいきました。

根本的な問題は、_callbackSetLabel の次の行と関係があります。

this._setValueFromItem(result[0], priorityChange);

これがまさに、値が結果リストの最初の値に設定されている理由です。なぜこれがこのようになっているのかわかりません。

うまくいったといいのですが、私たちは FilteringSelect.js のトランク バージョンを使用しています ( http://trac.dojotoolkit.org/browser/dijit/trunk/form/FilteringSelect.js ) 。

于 2009-07-30T11:06:52.170 に答える
0

pntさんのコメントに続いて…

この議論は、問題がどこにあるのかを明確にします。「ぼかし」では、クエリ文字列としてQueryReadStoreを使用して、サーバーが最後に再クエリを実行しDisplayedValueます。

私の例では、それは " Canada" になります。候補リスト (さらに上を参照) の 6 つの領域にその文字列が含まれており、クエリ文字列を含むすべての項目のアルファベット順のリストを返すようにサーバーがプログラムされていることを考えると(クエリ文字列で始まるものだけでなく)、候補リスト全体は再び次のようになります。が返され、FilteringSelectこれらの中から最初の項目が選択されます --- この場合は " Atlantic Canada" です。

私の分析が正しければ、可能な方法の 1 つは、クエリ サービスをリファクタリングして、クエリ文字列と完全に一致するアイテムをリストの先頭 (アルファベット順の前) に配置することです

于 2009-02-19T06:53:47.103 に答える