Jquery 脚本在 ASP.NET UpdatePanel 中没有按预期工作

Jquery script not working as expected in ASP.NET UpdatePanel

我正在创建一个嵌套的网格视图。我使用的示例来自:http://www.aspsnippets.com/Articles/ASPNet-Nested-GridViews-GridView-inside-GridView-with-Expand-and-Collapse-feature.aspx

问题是 "minus" 的脚本没有删除嵌套的 gridview。似乎发生的是 "plus" 函数似乎一次又一次地触发。

<script type = "text/javascript">
       $(document).ready(function () {
           $("[src*=plus]").on("click", function () {
               $(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>")
               $(this).attr("src", "images/minus.png");               
           });
           $("[src*=minus]").on("click", function () {
               $(this).attr("src", "images/plus.png");
               $(this).closest("tr").next().remove();
           });

       });

I am using an UpdatePanel (The 2 gridviews are Inside).

 <asp:UpdatePanel ID="UpdatePanel1" runat="server">
                          <ContentTemplate> 
 <script type="text/javascript">
   Sys.Application.add_load(BindEvents);
     </script>
     <asp:GridView ID="GridView1" runat="server"  Width = "100%" AutoGenerateColumns = "False" Font-Names = "Arial" CssClass="table table-hover table-bordered"
                            Font-Size = "11pt" AlternatingRowStyle-BackColor = "#F18903" HeaderStyle-BackColor = "#F18A07" AllowPaging ="True" 
                            DataKeyNames="Rut" OnPageIndexChanging  = "OnPaging" onrowediting="EditCustomer"  OnRowDataBound="OnRowDataBound" onrowupdating="UpdateCustomer" onrowcancelingedit="CancelEdit" >
                                 <Columns>
                                    <asp:TemplateField>
                                    <ItemTemplate>
                                     <img alt = "" style="cursor: pointer" src="images/plus.png" />
                                        <asp:Panel ID="pnlOrders" runat="server" Style="display: none">
                                        <asp:GridView ID="gvOrders" runat="server" AutoGenerateColumns="false" CssClass = "ChildGrid">
                                    <Columns>
                                         <asp:BoundField ItemStyle-Width="150px" DataField="Nombre" HeaderText="Order Id" />
                                         <asp:BoundField ItemStyle-Width="150px" DataField="Rut" HeaderText="Date" />
                                    </Columns>
                                    </asp:GridView>
                                    </asp:Panel>
                                    </ItemTemplate>
                                    </asp:TemplateField>

                                    <asp:TemplateField  HeaderText = "Nombre" >
                                       <ItemTemplate>
                                        <asp:Label ID="lblNombre" runat="server" Text='<%# Eval("Nombre")%>'></asp:Label>
                                       </ItemTemplate>     
                                    </asp:TemplateField>

                                   <asp:TemplateField   HeaderText = "Rut">
                                       <ItemTemplate >
                                        <asp:Label ID="lblRut" DataField="Rut" runat="server" Text='<%# Eval("Rut")%>'></asp:Label>
                                       </ItemTemplate>    
                                   </asp:TemplateField>

                                  <asp:TemplateField   HeaderText = "Fecha de Nacimiento">
                                     <ItemTemplate>
                                        <asp:Label ID="lblFecha_Nac" runat="server" Text='<%# Eval("Fecha_Nac")%>'></asp:Label>
                                     </ItemTemplate>
                                     <EditItemTemplate>
                                         <div class='input-group date' id='datetimepicker1'>
                                          <asp:TextBox ID="txtFecha_Nac" runat="server" Text='<%# Eval("Fecha_Nac")%>'></asp:TextBox>
                                            <span class="input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>                                  
                                         </div> 
                                    </EditItemTemplate> 
                                  </asp:TemplateField>


                                  <asp:TemplateField  HeaderText = "Celular">
                                     <ItemTemplate>
                                        <asp:Label ID="lblCelular" runat="server" Text='<%# Eval("Celular")%>'></asp:Label>
                                     </ItemTemplate>
                                     <EditItemTemplate>
                                        <asp:DropDownList ID="txtCelular" runat="server" >
                                            <asp:ListItem Text="SI" Value="1" />
                                            <asp:ListItem Text="NO" Value="0" />
                                        </asp:DropDownList>
                                    </EditItemTemplate> 
                                  </asp:TemplateField> 

                                    <asp:CommandField  EditText="Editar" ShowEditButton="True" />

                                    <asp:TemplateField HeaderText="Informacion Adicional" >
                                       <ItemTemplate>
                                         <asp:Button ID="Btn1" runat="server" 
                                            Text="Ver Mas" CommandArgument="Button1"
                                            OnClick="Btn1_Click"/>
                                        </ItemTemplate>
                                      </asp:TemplateField>

                                     <asp:TemplateField HeaderText="Cambio Final" >
                                       <ItemTemplate>
                                         <asp:Button ID="BtnCambio" runat="server" 
                                            Text="Check" CommandArgument="Button1"
                                            OnClick="Btn1_ClickCambioFinal"/>
                                        </ItemTemplate>
                                      </asp:TemplateField>

                                     <asp:TemplateField HeaderText="Image">
                                         <EditItemTemplate>
                                             <asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
                                         </EditItemTemplate>
                                         <ItemTemplate>
                                             <asp:Image ID="Image1" runat="server" />
                                         </ItemTemplate>
                                     </asp:TemplateField>
                                </Columns>

                                <AlternatingRowStyle BackColor="#FBEDBB"  />
                                 <HeaderStyle BackColor="#F18A07" />
                            </asp:GridView> 

                              </ContentTemplate>
                                <Triggers>
                                    <asp:AsyncPostBackTrigger ControlID = "GridView1" />
                                </Triggers>
                            </asp:UpdatePanel> 

我假设您需要重新订阅活动。 JavaScript是自上而下执行的,即订阅了事件后,后面创建的元素不会触发该事件。

像下面的例子:

function myEventHandler () {
    // In here you perform your event-specific code
    eventSubscription();
}

var eventSubscription = function () {
    // Make sure to unsubscribe to prevent event to fire multiple times
    $('.myClass').unbind('click');
    // Re-subscribe to event
    $('.myClass').on('click', myEventHandler);
}

// Call the eventSubscription to hook your events
eventSubscription();

正如 noMad17 所说,您需要在回发后重新订阅您的 js 方法,即使您使用的是 updatePanel。这是我的代码:

//js file:
$(document).ready(function () {
   loadConfiguration();
 });

function loadConfiguration()
{
     //add your configuration here
}    
//aspx file
<asp:UpdatePanel runat="server" ID="upnl1" UpdateMode="Conditional" >
        <ContentTemplate> 
            <script type="text/javascript">                                        
               Sys.Application.add_load(loadConfiguration);
            </script>
        <!--More code here...-->
</asp:UpdatePanel>

postback 后,UpdatePanel 和其中的所有内容都已构建,因此它将再次加载 add_load 中的 js 代码。

希望对您有所帮助

这是文档准备就绪时绑定什么事件的问题。

如果您想 "toggle" 在两个函数调用之间,有许多插件可以帮助您 (see this SO question)。

一个简单的实现方法是使用 Tushar Gupta 提到的 jquery one 函数。

function plus() {               
    $(this).closest("tr").after("<tr><td></td><td colspan = '999'>" + $(this).next().html() + "</td></tr>");
    $(this).attr("src", "images/minus.png");
    $(this).one("click", minus);
}
function minus() {
    $(this).attr("src", "images/plus.png");
    $(this).closest("tr").next().remove();
    $(this).one("click", plus);
}

$(document).ready(function(){
    $("[src*=plus]").one("click", plus);    
    //You might want to change the selector with a class 
    // to your img so you don't have to worry about 
    // opened or closed by default
});

希望对您有所帮助!

解释:

on 函数在调用时将事件绑定到 DOM 元素。在您的情况下,文档准备就绪时。 加载文档后,所有 table 行都显示展开图像。因此,"plus click" 函数绑定到所有 img 标签。 另一方面,没有元素显示减号(还)。所以没有绑定 "minus click" 函数。

on 函数不关心您是否更改元素属性。请记住,即使您通过属性进行筛选,您的选择器也会选择元素。

在您提供的link中,作者使用了live函数。此函数现已弃用,但它基本上是一个 on 函数,现在和将来都可以在选择器上使用。 on 函数不再是这种情况。