背景
我正在开发一个ASP.NETFramework4.8Web应用程序。
我的问题
每次服务器(代码隐藏)更改DOM时,我都需要运行一个JavaScript函数,在这种情况下,从Telerik RadGrid中添加或删除行。我需要在客户端使用某种侦听器,或者在ASP.NET Framework 4.8中是否有方法通知客户端。
工作流程及步骤
1:用户点击“添加项目”/“删除项目”链接。
2:服务器(代码隐藏)收到一个OnClick事件的通知。它向RadGrid添加或删除项目。
3:现在JavaScript需要知道服务器(代码后面)何时完成添加或删除该项目。这是如何实现的?
编号
包含用户从中选择项目的RadGrid的.ascx代码:
<telerik:RadGrid ID="rgPlayers" CssClass="data-table bottomSpace" runat="server" AutoGenerateColumns="False" Skin="Metro" Height="288px"
ForeColor="#333333" CellPadding="4" ShowFooter="false" GridLines="None" AllowSorting="true"
OnSortCommand="rgPlayers_Sorting" OnNeedDataSource="rgPlayers_NeedDataSource" OnItemDataBound="rgPlayers_RowDataBound"
onkeydown="gridKeyDown(event);">
<ClientSettings Selecting-AllowRowSelect="true" EnablePostBackOnRowClick="false" AllowKeyboardNavigation="true">
<KeyboardNavigationSettings EnableKeyboardShortcuts="false" AllowSubmitOnEnter="false" AllowActiveRowCycle="true" />
<Scrolling SaveScrollPosition="true" AllowScroll="true" UseStaticHeaders="true"></Scrolling>
</ClientSettings>
<MasterTableView ShowHeadersWhenNoRecords="true" DataKeyNames="ToPlsyer, PlayerNr ">
<Columns>
<telerik:GridTemplateColumn HeaderStyle-Width="150px">
<HeaderTemplate>
<table id="tablePlayerNr">
<tr>
<td>
<asp:LinkButton ID="lbPlayerNumber" CommandName="Sort" CommandArgument="PlayerNr" runat="server" Text="<%$Resources:PlayerNr%>"></asp:LinkButton>
</td>
</tr>
<tr>
<td>
<asp:TextBox ID="tbPlayerNumberSearch" runat="server" CssClass="rightSpace" onkeypress="return tbPlayerNumberSearch()"></asp:TextBox>
</td>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbLinkedPlayerNumber" runat="server" Text='<%# Bind("PlayerNr") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderStyle-Width="250px">
<HeaderTemplate>
<table id="tablePlayerDesc">
<tr>
<td>
<asp:LinkButton ID="lbDescription" CommandName="Sort" CommandArgument="PlayerDescription" runat="server" Text="<%$Resources:Global, Description%>"></asp:LinkButton>
</td>
</tr>
<tr>
<td>
<asp:TextBox ID="tbDescriptionSearch" runat="server" CssClass="rightSpace" onkeypress="return tbDescriptionSearch()"></asp:TextBox>
</td>
</tr>
</table>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbLinkedPlayerDescription" runat="server" Text='<%# Bind("PlayerDescription") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridNumericColumn DataFormatString="{0:F0}" HeaderStyle-Width="80px" ItemStyle-Width="80px" DataField="BalanceAvailable" HeaderText="<%$Resources:BalanceAvailable%>" AllowSorting="false"></telerik:GridNumericColumn>
<telerik:GridTemplateColumn HeaderStyle-Width="100px" ItemStyle-Width="100px">
<ItemTemplate>
<asp:LinkButton ID="lbPlayerAdd" runat="server" Text="<%$ Resources:Global, Add%>" OnClick="btnAddLinkedPlayer_Click"></asp:LinkButton>
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
当用户选择项目时,将所选项目添加到RadGrid或从中删除RadGrid:
<telerik:RadGrid ID="rgPlayers" CssClass="data-table bottomSpace" runat="server" AutoGenerateColumns="False" Skin="Metro" Height="200px" TabIndex="-1"
ForeColor="#333333" CellPadding="4" ShowFooter="false" GridLines="None" AllowAutomaticUpdates="true" AllowSorting="false"
OnItemDataBound="rgPlayers_RowDataBound" OnPreRender="rgPlayers_PreRender">
<ClientSettings Selecting-AllowRowSelect="true" Scrolling-SaveScrollPosition="true" Scrolling-AllowScroll="true" Scrolling-UseStaticHeaders="true">
</ClientSettings>
<MasterTableView ShowHeadersWhenNoRecords="true" TableLayout="Fixed" DataKeyNames="RowId">
<Columns>
<telerik:GridBoundColumn DataField="RowId" />
<telerik:GridBoundColumn DataField="SharedQuantity" />
<telerik:GridBoundColumn HeaderStyle-Width="120px" DataField="PlayerNr" HeaderText="<%$Resources:PlayerNr%>" ReadOnly="True" />
<telerik:GridBoundColumn HeaderStyle-Width="100%" ItemStyle-Width="100%" DataField="PlayerDescription" HeaderText="<%$Resources:Global, Description%>" ReadOnly="True" />
<telerik:GridTemplateColumn HeaderStyle-Width="100px" ItemStyle-Width="100px">
<HeaderTemplate>
<asp:Label ID="lbHeaderQuantityText" runat="server" Text="<%$Resources:Global, Quantity%>"></asp:Label>
</HeaderTemplate>
<ItemTemplate>
<asp:Label ID="lbQuantity" runat="server" Text='<%# Bind("Quantity") %>' CssClass="float-left" />
<asp:ImageButton ID="btnAddQty" OnClick="btnAddQty_Click" CommandArgument='<%# Eval("RowId","{0}") %>' Height="18px" Width="18px" runat="server" CssClass="leftSpace float-left" ImageUrl="~/Images/plus.png" />
<asp:ImageButton ID="btnRemoveQty" OnClick="btnRemoveQty_Click" CommandArgument='<%# Eval("RowId","{0}") %>' Height="18px" Width="18px" runat="server" CssClass="leftSpace float-left" ImageUrl="~/Images/minus.png" />
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridNumericColumn HeaderStyle-Width="60px" ItemStyle-Width="60px" FooterStyle-HorizontalAlign="Right" HeaderStyle-HorizontalAlign="Right" ItemStyle-HorizontalAlign="Right" DataField="PriceInclVat" DataFormatString="{0:F2}" HeaderText="<%$Resources:Global, UnitPriceColumn%>" ReadOnly="True" />
<telerik:GridNumericColumn HeaderStyle-Width="75px" ItemStyle-Width="75px" DataField="Balance" DataFormatString="{0:F0}" HeaderText="<%$Resources:BalanceAvailable%>" ReadOnly="True" />
<telerik:GridTemplateColumn HeaderText="<%$Resources:ToPlsyer%>" HeaderStyle-Width="100%" ItemStyle-Width="100%" UniqueName="PlayerNr" DataField="ToPlsyer">
<ItemTemplate>
<telerik:RadTextBox runat="server" CssClass="integer" Text='<%#Eval("ToPlsyer") %>' OnTextChanged="OnTextChanged" AutoPostBack="True" ID="MainPlayerTextbox" />
</ItemTemplate>
</telerik:GridTemplateColumn>
<telerik:GridTemplateColumn HeaderStyle-Width="60px" ItemStyle-Width="80px">
<ItemTemplate>
<asp:LinkButton ID="lbRemove" CssClass="" runat="server" Text="<%$ Resources:Global, Delete%>" CommandArgument='<%# Eval("RowId","{0}") %>' OnClick="btnRemovePlayerItem_Click" />
</ItemTemplate>
</telerik:GridTemplateColumn>
</Columns>
</MasterTableView>
</telerik:RadGrid>
单击“添加项”或“删除项”链接时在代码后面调用的方法:
protected async void btnAddLinkedPlayer_Click(object sender, EventArgs e)
{
ResetUnlinkedPlayerHtml();
HideSearchPlayerhWarning();
Player resultPlayer = null;
string toPlayer = (string)((GridDataItem)((Control)sender).BindingContainer).GetDataKeyValue(nameof(Player.ToPlsyer));
string playerNr = (string)((GridDataItem)((Control)sender).BindingContainer).GetDataKeyValue(nameof(Player.PlayerNr));
if (!string.IsNullOrEmpty(playerNr))
{
resultPlayer = LinkedPlayers.Find(player => player.PlayerNr == playerNr);
}
if (resultPlayer != null)
{
PlayerOrderRow matchPlayer = PlayerOrderRows.Find(playerOrderRow => playerOrderRow.PlayerNr == resultPlayer.PlayerNr && playerOrderRow.ToPlsyer == toPlayer && resultPlayer.PlayerDescription == playerOrderRow.PlayerDescription && playerOrderRow.Unlinked == false);
if (matchPlayer == null)
{
try
{
resultPlayer.PriceInclVat = await GetPriceForPlayer(playerNr, 1, GetSetting().UserInformation, ddlDeliveryWH.SelectedItem.Value);
}
catch (Exception ex)
{
SetUserMessage(ex);
}
PlayerOrderRow row = new PlayerOrderRow(resultPlayer.PlayerNr, resultPlayer.PlayerDescription, 1, resultPlayer.BalanceAvailable, toPlayer, IsThisAWarrantyCase || IsThisAGoodwillCase ? 0 : resultPlayer.PriceInclVat, resultPlayer.PriceInclVat);
PlayerOrderRows.Add(row);
}
else
{
matchPlayer.Quantity += 1;
}
BindSelectedPlayerOrderRowsToGrid(PlayerOrderRows, SessionConstants.CurrentPlayerNumber.TrimToEmpty(), SessionConstants.RepurchaseCaseReceipt);
}
}
问题及总结
当服务器端(代码隐藏)完成向RadGrid添加项目时,客户端的JavaScript是否有任何方法得到通知?
谢谢!
1条答案
按热度按时间polkgigr1#
通知服务器代码完成是什么意思?
你不能异步运行服务器端代码。事件存根可以异步调用其他例程,但是服务器端代码必须100%完成。
当服务器端(代码隐藏)完成时,客户端的JavaScript是否有任何方法得到通知
你已经知道了!!!-如果第一步是发生并运行后面的事件代码,那么这就是你如何知道的!!!
后面的代码不能等待,也不能异步运行。您的后面的代码必须始终100%完成其代码,然后整个网页被发送回客户端。客户端再次加载整个页面,然后任何JavaScript代码(如OnReady上的page.load)再次开始运行。
所以当你点击一个按钮时,整个页面会传送到Web服务器。Web服务器然后加载-获取那个类对象并从头开始初始化它。(代码中的值和变量在你每次点击一个按钮并发布- bck时从头开始)。
然后你的代码开始运行,并且只能在很短的时间内修改那个页面,而整个网页都在服务器上。当代码完成后,页面就返回到客户端。
你的代码永远不会直接与用户交互。它只能在很短的时间内修改网页,或者在页面现在在服务器上的所谓“往返”期间修改网页。这也是为什么你的按钮点击事件代码不能是异步的。后面的代码可以改变网页上的东西,但是用户将看不到任何东西,直到这样的时候,后面的代码是100%完成。当代码是100%完成?
然后,整个网页返回到客户端,客户端呈现结果,JavaScript例程重新加载并开始运行。
现在JavaScript需要知道服务器(代码隐藏)何时完成添加或删除该项目。这是如何实现的?
因为第一步发生了-这就是你知道的。如果第一步没有发生,那么其他的也不会发生。
如果网页没有返回到服务器,代码就不可能修改网页上的任何内容。因此,当网页在服务器上运行时,代码只能在非常小的窗口中更改内容。
所以,如果步骤1发生并且回发发生,您就知道是否发生了变化。在客户端运行的JavaScript?它不会知道,直到回发和网页返回到客户端。当发生时,JavaScript现在重新开始-并且只有刚刚从服务器返回的当前页面的内容-而不是前一个页面和数据-它早就消失了。因此,没有办法检测任何更改,因为您刚刚将一个全新的页面发送回客户端。
现在你可以按一下按钮做一 AJAX 调用。这意味着没有往返,也没有页面回发。但话又说回来,当你做这样的调用,那么后面的代码就不能更新网页。你必须编写JavaScript代码来获得结果并重新绘制网格客户端。但我不明白为什么只使用后面的代码和按钮单击作为“假设”的触发器。我的意思是,除非用户点击一个按钮,否则网格不会改变,对吗?