【问题标题】:jQuery Dialog 'Close' conflict with ASP.NET UpdatePaneljQuery 对话框“关闭”与 ASP.NET UpdatePanel 冲突
【发布时间】:2012-05-16 05:59:10
【问题描述】:

我有一个带有以下内容的 ASP.NET UpdatePanel:

<asp:UpdatePanel ID="UpdatePanel3" runat="server" UpdateMode="Conditional">
<ContentTemplate>
    <%-- jQuery dialog - Suppliers --%>
    <div id="divSuppliers" style="display: none;">
        <asp:ListBox ID="lstSuppliers" runat="server" SelectionMode="Single" Rows="10" Width="100%"
            DataValueField="SupplierID" DataTextField="SupplierName">
        </asp:ListBox>
        <br /><br />
        <asp:Button ID="btnSelectSupplier" runat="server" Text="Select 2" OnClick="btnSelectSupplier_Click" />
    </div>

    <asp:GridView ID="gvSuppliers" runat="server" AutoGenerateColumns="false" SkinID="gvSkin"
        DataKeyNames="SupplierID" EmptyDataText="No Existing User Roles">
        <Columns>
            <asp:TemplateField HeaderText="Supplier Name">
                <ItemTemplate>
                    <asp:Label ID="lblSupplierName" runat="server" Text='<%# Eval("SupplierName") %>'></asp:Label>
                </ItemTemplate>
            </asp:TemplateField>
        </Columns>
    </asp:GridView>

    <asp:Button ID="btnAddSupplier" runat="server" Text="Add Supplier" 
        Visible="false" OnClick="btnAddSupplier_Click" />

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

很简单,真的。只不过是一个用于 jQuery 对话框弹出窗口的 div、一个带有单列的 ASP.NET GridView 控件,以及一个用于异步回发的 ASP.NET 按钮。

这里是处理 btnSelectSupplier 异步回发的 click 事件。

protected void btnSelectSupplier_Click(object sender, EventArgs e) {

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+=    
    // WORKS JUST FINE
    List<SupplierItem> suppliers = new List<SupplierItem>();    

    foreach (int i in lstSuppliers.GetSelectedIndices()) {
        suppliers.Add(
            new SupplierItem { SupplierID = Convert.ToInt32(lstSuppliers.Items[i].Value), SupplierName = lstSuppliers.Items[i].Text });
        lstSuppliers.Items[i].Selected = false;
    }

    gvSuppliers.DataSource = suppliers;
    gvSuppliers.DataBind();

    // +=+=+=+=+=+=+=+=+=+=+=+=+=+=
    // DOES NOT WORK!!
    string jq = "$('#divSuppliers').dialog('close');";

    ScriptManager sm = ScriptManager.GetCurrent(this);
    if (sm != null && sm.IsInAsyncPostBack) {
        ScriptManager.RegisterClientScriptBlock(
            this, typeof(Page), Guid.NewGuid().ToString(),
            jq, true);
    }
}

问题: GridView 将在异步回发期间正常更新(参见上面的点击事件);但是,jQuery 对话框拒绝关闭(再次,请参阅上面的事件以及它说不工作的地方)。我正在页面上的 ScriptManager 中注册 javascript (jquery),因此它应该正在执行并关闭对话框,但由于某种原因它没有。

编辑: 打开 jQuery 对话框并使其成为模态的代码。

protected void btnAddSupplier_Click(object sender, EventArgs e) {
    lstSuppliers.ClearSelection();
    lstSuppliers.DataSource = Suppliers.GetAllSuppliers();
    lstSuppliers.DataBind();

    string jq = "var dlg = $('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); dlg.parent().appendTo($('form:first'));";

    ScriptManager sm = ScriptManager.GetCurrent(this);
    if (sm != null && sm.IsInAsyncPostBack) {
        ScriptManager.RegisterClientScriptBlock(
            this, typeof(Page), Guid.NewGuid().ToString(),
            jq, true);
    }
}

【问题讨论】:

  • 你能显示你的 jquery 代码吗?我可以解决这个问题...
  • 唯一相关的 jQuery 包含在我上面的代码中(参见点击事件代码)。由于某种原因,对话框关闭不起作用 - 仅此而已。
  • 您是否尝试过在 JS 控制台(如 Firebug 或 Safari/Chrome 的开发者控制台)中执行 $('#divSuppliers').dialog('close');
  • 你的页面包含了 jQuery UI 库,对吧?

标签: jquery asp.net updatepanel


【解决方案1】:

用于 jQuery UI Dialog 的 div 应该在 UpdatePanel 之外。

btnAddSupplier_Click 上,您创建对话框并将其移到更新面板之外。
btnSelectSupplier_Click 之后,您有 2 个具有 divSuppliers id 的 div,移动的一个和一个 received from server(UpdatePanel 机制允许通过使用从服务器返回的 html 重建整个 UpdatePanel DOM 来进行部分页面更新)。

我还建议使用console.log 来帮助调试。
添加到关闭对话框js:console.log($('#divSuppliers'))

【讨论】:

  • 您将 jQuery 对话框移到更新面板之外可能是对的。起初我实际上是这样的,但由于某种我不记得的原因,我将它移到了更新面板中。我不会无缘无故地把它搬到那里。无论如何,我将不得不做更多的测试,看看当我有一些额外的时间时它是否有效。我仍然认为我只是要撕掉 .net 垃圾,而是使用带有 AJAX 的 jQuery。
  • 更新更新面板时,它的整个 html 将被删除并使用从服务器返回的内容进行更新,包括对话框 div,因此您剩下 2 个具有相同 id 的 div,即您移出的那个和从更新面板更新中重新创建的那个。
  • 您应该在更新面板之外创建一个新的空divSuppliersDialog 并将其用于对话框。在显示之前,您必须使用RegisterClientScriptBlockdivSuppliers 移动为divSuppliersDialog 的子项(就像您已经做的那样)。
  • UpdatePanel 是一个很重的机制。使用 jQuery ajax 代替 UpdatePanel 将是明智之举。我建议在下一个项目中尝试ASP.NET MVC
  • 我知道 .NET 的 AJAX 解决方案(脚本管理器和更新面板)和 jQuery 之间的区别。 .NET 的解决方案虽然调用更多开销,但可以更简单地实现。使用 jQuery AJAX 往往需要更多时间来设置,或者至少在我的经验中是这样。关于 ASP.NET MVC,我意识到它比 Web 应用程序更适合 jQuery,但这一事实本身并不意味着人们应该仅仅因为 Web 应用程序使用 jQuery 而使用 MVC。感谢您对此的帮助。
【解决方案2】:

您是否考虑过采用更简单的路线并将事件绑定到按钮客户端以关闭对话框?

 $(function () {
    $('#btnSelectSupplier').click(function () {

        $('#divSuppliers').dialog('close');
    });
});

从用户的角度来看,流程仍然相同。他们单击按钮,对话框关闭。服务器端代码将在对话框关闭后运行,但由于似乎没有任何服务器端逻辑决定您是否要在单击后关闭对话框,这可能符合您的需求。

编辑我明白你的问题。您遇到了问题,因为您没有打开现有对话框,而是在单击时重新定义对话框:

 string jq = "var dlg = $('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 }); dlg.parent().appendTo($('form:first'));";

相反,您想在 document.ready 函数中定义对话框。

 $(function () {
    //define the div as a dialog. By default, it will not open until you tell it to
$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 });

});

点击后,你应该像这样打开它

 $('#divSuppliers').dialog('open');

再一次,您可能希望在客户端执行此操作,而不是尝试将脚本推送到服务器端事件的页面中,但这取决于您。

最简单的完整解决方案:

$(function () {

$('#divSuppliers').dialog({ modal: true, draggable: true, title: 'Suppliers', width: 500 });

$('#btnAddSupplier').click(function () {

    $('#divSuppliers').dialog('close');
});
$('#btnSelectSupplier').click(function () {

    $('#divSuppliers').dialog('open');
});
});

【讨论】:

  • 这有效,但仅在我第一次单击 btnSelectSupplier 时。如果我重新打开对话框(通过单击不同的按钮来完成)然后单击 btnSelectSupplier 它不会关闭对话框。我在 btnSelectSupplier 单击事件中添加了一个警报,以确保每次单击按钮时都会触发它,并且确实显示了警报。几乎就像在第一次关闭后找不到 jquery 对话框的 div。
  • 我在看到您的更新后更新了我的答案。您在单击时重新定义对话框,而不是调用 .dialog('open') 函数。
【解决方案3】:

因此,解决方案如下:不要尝试将 ASP.NET UpdatePanel 与 jQuery Dialog 混合使用,因为它们不能很好地配合使用。

我之所以选择这个方向,是因为我认为通过使用 .NET 的 ScriptManager 和 UpdatePanel 控件而不是全部在 jQuery 中完成 AJAX 将花费我更少的时间。在这一点上,我似乎错了,因为我要回去撕掉 .NET 垃圾并用 jQuery 替换它。所以我以为我会节省的所有时间都像风一样消失了。

故事的寓意:如果没有必要,不要将两者混为一谈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-16
    • 1970-01-01
    • 2015-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多