1

長々と申し訳ありません。ファンシーなタイプアヘッドで遊んでいて、説明できない問題に遭遇しました。私は修正を見つけましたが、修正は意味をなさないので、誰かが私の例を見て何が起こっているのかを説明できるかどうか、そしてそれが何らかのバグであるかどうか疑問に思っています? 必要最小限の例を示すために、ほとんどの機能を取り除いています。

シナリオ: 派手なタイプアヘッドを備えたテキスト ボックスがあります。その横に、新しく見つかった値を 2 番目のフィールドに追加するボタンがあります。2 番目のフィールドを使用して、現在までに選択されたすべての値を表示する繰り返しコントロールを操作します。以下のコード

結果: これをテストするには、フィールドに「ab」と入力し、任意の選択肢を選択してから、「追加」リンクをクリックします。ご想像のとおり、繰り返しは (, abcd) を示しています。テスト 2、そのプロセスを 2 回繰り返します。繰り返しには (, abcd, ab, abcd) が表示されます。何らかの理由で、「ab」が 2 番目のフィールドに追加されています。3 番目のテスト - ab と入力し、選択肢を選択して追加します。「bc」と入力し、選択肢を選択して追加します。cd と入力しますが、選択肢を選択する代わりに、保存ボタンをクリックします。次に、繰り返しは (, abcd, bc, abce, cd) を示します。私はそれをまったく説明できません。

回避策: これを適切に機能させるには、リンクの更新タイプを部分的から完全に変更します。なぜこれが機能するのかわかりませんが、機能します。本当にやりたいかどうかはわかりませんが、やむを得ない場合はそうします。これはかなり複雑な形式であり、必要がない限り完全な更新は行いません。

コード: これは、問題を示す縮小された xpage です。

<?xml version="1.0" encoding="UTF-8"?>
<xp:view xmlns:xp="http://www.ibm.com/xsp/core" xmlns:xc="http://www.ibm.com/xsp/custom">
    <xp:this.data>
        <xp:dominoDocument var="document1" formName="Test">
        </xp:dominoDocument>
    </xp:this.data>
    <xp:panel id="mainPanel">
        <xp:button value="Save" id="button1">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="complete">
                <xp:this.action>
                    <xp:saveDocument var="document1"></xp:saveDocument>
                </xp:this.action>
            </xp:eventHandler>
        </xp:button>
        <xp:inputText id="objName1" value="#{document1.objName}">
            <xp:typeAhead mode="full" minChars="2" valueMarkup="true"
                var="searchValue" id="typeAhead1">
                <xp:this.valueList><![CDATA[#{javascript:   //In here I usually do some searching to find a result set, but for the purposes of a test, let's just do an array
    var mapResults:java.util.TreeMap = new java.util.TreeMap();
    mapResults.put("abcd", "abcd");
    mapResults.put("abce", "abce");
    mapResults.put("abcf", "abcf");
    mapResults.put("abcg", "abcg");
    mapResults.put("abch", "abch");
    mapResults.put("abci", "abci");
    //Now format the results
    var returnList = "<ul>";
    //All results are in the TreeMap and are sorted.  Now add them to the output
    var iter:Iterator = mapResults.entrySet().iterator();
    while (iter.hasNext()) {
        var nextEntry = iter.next();
        returnList += "<li>" + nextEntry.getValue() +"</li>";
    }
    //Lastly, close off the UL tag and return
    returnList += "</ul>";
    return returnList;}]]></xp:this.valueList>
            </xp:typeAhead>
        </xp:inputText>
        <xp:link escape="true" text="Add Another Object" id="link1">
            <xp:eventHandler event="onclick" submit="true"
                refreshMode="partial" id="eventHandler1" refreshId="mainPanel">
                <xp:this.action><![CDATA[#{javascript:var currentVals = document1.getItemValueArray("addObjName");
//check for null value in first item in array - happens
//if we clear the array from the 'cross' buttons in the repeat
if (currentVals[0] == null) {
    currentVals = new Array("");
}
//get the value from the object name field and whack it on the end
var newValue = getComponent("objName1").getValue();
//Put the value into a test field so we can prove that the value wasn't added below
document1.replaceItemValue("test1", newValue);
//Now add it to the field - where is the search text coming from?
currentVals.push(newValue);
document1.replaceItemValue("addObjName", currentVals);
getComponent("objName1").setValue("");
}]]></xp:this.action>
            </xp:eventHandler>
        </xp:link>
        <xp:repeat id="repeat1" rows="30" var="rowData" indexVar="index"
            repeatControls="false">
            <xp:this.value><![CDATA[#{javascript:document1.getItemValueArray("addObjName")}]]></xp:this.value>
            <xp:panel tagName="div">
                <xp:link escape="true" id="link2" title="Remove from list">
                    <xp:image url="/vwicn081.gif" id="image1">
                        <xp:eventHandler event="onclick" submit="true"
                            refreshMode="partial" refreshId="mainPanel" id="eventHandler2">
                            <xp:this.action><![CDATA[#{javascript://remove an entry (string) from a list of strings (thanks to Mark Leusink)
Array.prototype.removeEntry = function( entry:String ) {
  if ( @IsNotMember(entry, this)) {
    return this;
  }
  var res = @Trim( @Replace(this, entry, "") );
  return (typeof res == "string" ? (res.length==0 ? [] : [res]) : res);
}
var oldArray:Array = document1.getItemValueArray("addObjName");
var myArray = oldArray.removeEntry(oldArray[index]);
document1.replaceItemValue("addObjName", myArray);
}]]></xp:this.action>
                        </xp:eventHandler>
                    </xp:image>
                </xp:link>
                <xp:text escape="true" id="computedField1" value="#{javascript:rowData}">
                </xp:text>
            </xp:panel>
        </xp:repeat>
        <xp:text escape="true" id="computedField2">
            <xp:this.value><![CDATA[#{javascript:"and here is what was added in the link:"}]]></xp:this.value>
        </xp:text>
        <xp:text escape="true" id="computedField3" value="#{document1.test1}">
        </xp:text>
    </xp:panel>
</xp:view>

テイカーはいますか?これについて論理的な説明はありますか、それとも回避策を使用して衒学者になるのをやめるべきですか?

更新 上記の XPage を使用して、次のシナリオを複製することもできます。

ステップ 1: フィールドに「abc」と入力し、選択肢から「abcd」を選択して、「追加」リンクをクリックします。すべて良い。

ステップ 2: 「ab」と入力して待機し、次に「c」と入力して「abce」を選択します。もう一度追加します。これにより、ab、abc、abce が追加されます。

ステップ 3: ab と入力してから待ち、次に c と入力します。選択肢を選択せず​​に [保存] をクリックします。これにより、リンクをクリックして値を 2 番目のフィールドに追加していなくても、ab、abc が追加されます。

ステップ 4: ab と入力し、wait と入力し、c と入力して「abcf」を選択し、[追加] をクリックします。今回はabcfのみ追加。

これを以下のスヴェンの答えと一致させようとしています。部分的な更新は機能するので、彼が正しいことはわかっています。上記のステップ 2 で、先行入力コードが 2 回実行され、そのたびにリンクの onClick イベントがトリガーされ、最後にリンクの onClick イベントが実行されていると考えています。ステップ 3 でも同様です。この例では、リンクはまったくクリックされていませんが、onClick コードはまだ実行されています。ステップ 4 では、保存後に先行入力が 2 回実行されていますが、今回は onClick コードは実行されていません。

今では、たとえそれが好きでなくても、理解できると思います。Sven が言うように、$$xspsubmitid は、最後の送信アクションでデータをサーバーに送信した要素を識別します。したがって、この場合、以前の送信状態が記憶され、それが繰り返されます。したがって、単純な保存の直後に実行している場合、余分なコードは取得されませんが、リンクのイベントの後に実行している場合は送信されます。リンクと同じ方法でページをオンクリック コードで完成させます。

こうするのがいいのには理由があるのだろうけど、頭が痛くて問題が解決!ありがとうスヴェン!

4

1 に答える 1

2

フィールド/配列の値を更新するのはタイプアヘッドです。入力ボックスに 2 文字以上入力すると、入力ボックスの現在のデータがサーバーに送信され、ドキュメントの値が更新されます。リンクをクリックすると、値が再び追加されます。

編集: 先行入力のモードを「部分」に変更することでこれを修正できます

編集 2: typeahed の更新モードの違いは、データがサーバーに送信される方法です。完全更新の場合、データはPOST要求で送信され、部分更新の場合、データは次のように送信されます。GETリクエスト。

さまざまな HTTP リクエストを見てみましょう。

1.) 部分モード

部分モード / HTTP GET

2.) フルモード

フルモード / HTTP POST

2 つの図でわかるように、フル モードではサーバーに送信される「フィールド」が多くなります。興味深いのは$$xspsubmitidです: 現在は空です。しかし、リンクをクリックするとすぐに、フィールドにはリンクの ID が入力されます。

リンクがクリックされました

$$xspsubmitidは、データをサーバーに送信した要素を識別します。この場合、リンクとサーバーがリンクのコードを処理します。

そして、フルモードでの先行入力の問題が発生します。 ここに画像の説明を入力

ご覧のとおり、$$xspsubmitidは常に POST リクエストに追加されるため、サーバーは先行入力リクエストごとにリンクのクリック イベントを実行します。

于 2013-09-13T08:36:28.143 に答える