1

このシナリオを機能させるために、ここ数日間、頭を壁にぶつけてきました。

外部トリガーがあり、 Telerikを<asp:UpdatePanel>含むページがありますRadListView

<asp:UpdatePanel runat="server" ID="RationUpdatePanel" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
    <telerik:RadListView ID="RationListView runat="server"
        DataSourceId="RationDataSource" 
        OnItemCanceling="ItemCancelingHandler"
        OnItemEditing="ItemEditingHandler"
        OnItemUpdating="ItemUpdateHandler">
        <LayoutTemplate>
            <table>
               <thead>
                   <tr>...</tr>
               </thead>
               <tbody>
                   <tr id="itemPlaceHolder" runat="server"/>
               </tbody>
            </table>
        </LayoutTemplate>
        <ItemTemplate>
            <tr>
               <td>
                   <asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit" ToolTip="Edit" />&nbsp;
                   <asp:LinkButton ID="DeleteButton" runat="server" CausesValidation="False" CommandName="Delete" Text="Delete" ToolTip="Delete" />
               </td>
               <td>...</td>
             </tr>
        </ItemTemplate>
        <EditItemTemplate>
            <tr>
               <td>
                   <asp:LinkButton ID="SaveButton" runat="server" CausesValidation="False" CommandName="Save" Text="Save" ToolTip="Save" />&nbsp;
                   <asp:LinkButton ID="CancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel" ToolTip="Update" />
               </td>
               <td>...</td>
             </tr>
        </EditItemTemplate>
    </telerik:RadListView>
</ContentTemplate>
<Triggers>
    <asp:AsyncPostBackTrigger ControlID="UseRationButton" EventName="Click" />
</Triggers>
</UpdatePanel>

コードビハインドは次のようになります。

    protected void RationListView_ItemEditing(object sender, RadListViewCommandEventArgs e)
    {
        ((RadListViewDataItem)e.ListViewItem).Edit = true;
    }

    protected void RationListView_ItemCanceling(object sender, RadListViewCommandEventArgs e)
    {
        RationListView.ClearEditItems();
        ((RadListViewDataItem)e.ListViewItem).Edit = false;
    }

EditButtonまたはをクリックするとCancelButton、予想されるイベントが生成され、ObjectDataSource ルーチンが呼び出されてリストが再バインドされますが、更新パネルは更新されません。イベント ハンドラから呼び出しRationUpdatePanel.Update()ても状況は変わりません。コードは更新パネルの外で正しく機能します。モードが変更され、他のテンプレートのボタンが表示されます。

どちらのシナリオでも、外部トリガーをクリックするとリストが表示されます。

更新: beginRequest と endRequest のために、ブラウザーの PageManager クラスにいくつかの JavaScript コールバックを追加しました。これらは、イベントが発生したときにアラートを表示するだけです。

このページには、基本的に次のようないくつかの要素が含まれています (詳細は省略)。

<div>
    <div>
        <asp:DropDownList ID="RationDdl"/>
        <asp:Button ID="UseRationButton"/>
    </div>
    <div>
        <asp:DropDownList ID="AnimalGroupDdl"/>
        <asp:UpdatePanel ID="AnimalWeightUpdatePanel"/>
            <ContentTemplate>
                <asp:DropDownList ID="AnimalWeightDdl"/>
            </ContentTemplate>
        </asp:UpdatePanel>
    </div>
</div>
<div>
    <telerik:RadListBox>
    </telerik:RadListBox>
</div>
<div>
    <asp:UpdatePanel ID="FeedPreviewUpdatePanel">
        <ContentTemplate>
            <asp:Repeater>
            </asp:Repeater>
        </ContentPanel>
    </asp:UpdatePanel>
</div>  
<div>
    <!-- this contains the update panel shown above -->
</div>

最初のUseFeedRationButtondiv の は、 の外部トリガーですRationUpdatePanelAnimalGroupDdlの外部トリガーですAnimalWeightUpdatePanel。SelectedIndexChanged イベントのハンドラーは、選択したグループで使用可能な重みクラスをAnimalGroupDdl取り込みます。またはAnimalWeightDdlとの相互作用はありません。RationUpdatePanelFeedPreviewUpdatePanel

のマークアップは次のUseRationButtonとおりです。

            <asp:Button ID="UseRationButton" runat="server" 
                Text="Use This Ration" 
                OnClick="UseRationButton_Click" 
                CausesValidation="true" 
                ValidationGroup="UseRation" 
                UseSubmitBehavior="false">
            </asp:Button>&nbsp;

コードビハインドは次のとおりです。

    protected void UseRationButton_Click(object sender, EventArgs e)
    {
        string text = this.RationDdl.SelectedItem.Text;
        this.RationNameLabel.Text = text;
        this.RationDataSource.SelectParameters["RationId"].DefaultValue = this.RationDdl.SelectedValue;
    }

私がテストしたシナリオは 2 つあります。

1) 配給を選択しRationDdlてクリックUseRationButton 2) 動物グループを選択し、シナリオ 1 を実行します。

シナリオ 1 では、クライアント側の asp.net コードによって非同期ポストバックが開始され、ボタン イベントがサーバー側で処理されます。RatioListView は読み込まれますが、クライアント側の endRequest コードは実行されません (アラートは表示されません)。その後 RadListView 内のコントロールをクリックすると、非同期ポストバックがトリガーされますが、リストの状態は変更されず、クライアント側の endRequest コードは実行されません。

シナリオ 2 では、非同期ポストバックが開始され、イベントはサーバー側で処理され、AnimalWeightDdl入力されます。この場合、クライアント側の endRequest コードが実行されます (アラート IS が表示されます)。この後、配給を選択して [配給を使用] ボタンをクリックすると、ポストバックが開始され、リスト ビューにデータが入力されて endRequest コードが実行されます。リスト ビューのボタンをクリックすると、非同期ポストバックが開始され、リストの状態が変更され、endRequest コードが実行されます。

私の作業理論では、何かがクライアントのページ要求マネージャー クラスの状態を狂わせているというものですが、何が原因なのかはわかりません。

4

2 に答える 2

0

私が金曜と土曜の朝遅くに行った調査で、この問題に対する答えが得られました。

Sys.WebForms.PageRequestManager新しい配給の一時的なタイトルを含むテキスト ボックスを更新する endRequest イベントにいくつかのコードを添付しました。コードは次のようになります。

    ///
    /// reregister the change handlers after reloading the animal weight ddl and create a 
    /// temporary name for the ration based on animal choice and weight.
    ///
    function animalWeightDdlOnLoad() {
        var ddl = document.getElementById("<%= AnimalWeightDdl.ClientID %>");

        //
        // add event handler in a browser agnostic fashion
        //
        if (ddl.addEventListener) {
            ddl.addEventListener("change", animalWeightDdlOnChange);
        }
        else if (ddl.attachEvent) {
            ddl.attachEvent("onchange", animalWeightDdlOnChange);
        }
        else {
            ddl.onchange = animalWeightDdlOnChange;
        }

        animalWeightDdlOnChange();
    }

animalWeightDdlOnChange()動物の体重 ddl のオプション リストを参照しました。

    ///
    /// create a temporary name for the ration
    ///
    function animalWeightDdlOnChange() {
        var ddl1 = document.getElementById("<%= AnimalGroupDdl.ClientID %>");
        var ddl2 = document.getElementById("<%= AnimalWeightDdl.ClientID %>");
        var text = document.getElementById("<%= RationNameText.ClientID %>");
        text.value = ddl1.options[ddl1.selectedIndex].text + ' ' + ddl2.options[ddl2.selectedIndex].text + ' - Copy';
    }

ただし、リストがまだ作成されていない場合、オプションへの参照によってエラーが発生し、endRequest の処理が停止していました。すべての非同期リクエストでこのコードを実行するのではなく、次のように、動物グループ ddl の変更イベントのハンドラーになるように変更しました。

    function animalGroupDdlOnSelectedChanged() {
        //
        // add a handler for the endRequest event which will be triggered by
        // fetching the contents of the weight ddl.
        //
                         Sys.WebForms.PageRequestManager.getInstance().add_endRequest(animalWeightDdlOnLoad);
    }

次にanimalWeightDdlOnLoad()、リクエストが実行されたらハンドラーを削除する行を追加しました。これにより、重み ddl の変更ハンドラーは、リストが入力された後にのみ実行されるようになりました。問題が解決しました。しかし、念のため、動物の体重 ddl のオプション リストの長さにチェックを追加しました。

そのため、一見無害な JavaScript でさえ、ブラウザでの非同期リクエスト処理を混乱させる可能性があります。

于 2013-08-12T14:54:17.770 に答える
0

まず、telek rad control を使用している場合は、 に変更することをお勧めしasp:buttonますtelerik:RadButton
ここに例があります

  <telerik:RadButton ID="v" runat="server" Text="Use This Ration"
         AutoPostBack="true" 
  ValidationGroup="UseRation" OnClick="UseRationButton_Click">
  </telerik:RadButton>


  protected void UseRationButton_Click(object sender, EventArgs e)
    {
     string text = this.RationDdl.SelectedItem.Text;
    this.RationNameLabel.Text = text;
    this.RationDataSource.SelectParameters["RationId"].DefaultValue = this.RationDdl.SelectedValue;
    }

AutoPostBack="true"radButtonに追加する必要があることに注意してください。
また、このリンク、MSDN Reference1およびMSDN Reference2には、更新パネルの使用に関する詳細が表示されます。

于 2013-08-10T04:09:23.710 に答える