场景:
我有一个包含当前操作顺序的网站页面:
- 转发器列表(LIST 1)包含具有OnClick呼叫的按钮
- 按下这些按钮调用代码隐藏方法并更新更新面板
- 更新面板包含另一个列表(列表2),其中包含更多按钮,现在包含OnClientClick调用
- 按下列表2的按钮将新行添加到列表2
问题:
向列表2添加行是有效的,但只有一次!如果我试图再次按下列表2的某个按钮,包含列表2的整个div块就会消失。
代码:
清单1
<asp:Repeater ID="rptProjetos" runat="server">
<HeaderTemplate>
<table class="table table-striped border dtInit">
<thead>
<tr>
<th>Projeto</th>
<th>Data Inicio</th>
<th>Data Término</th>
<th>Nº Alocados Atualmente</th>
<th></th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><%# DataBinder.Eval(Container.DataItem, "Nome") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "DataInicio", "{0: dd/MM/yyyy}") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "DataTermino", "{0: dd/MM/yyyy}") %></td>
<td><%# DataBinder.Eval(Container.DataItem, "ContagemAlocados") %></td>
<td><asp:Button Text="Gerenciar" runat="server" ID="btnGerenciarProjeto" class="btn btn-dark"
CommandArgument='<%# DataBinder.Eval(Container.DataItem, "IdProjeto") %>'
OnClick="btnGerenciarProjeto_Click" UseSubmitBehavior="false"></asp:Button></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
更新面板
<asp:UpdatePanel runat="server" ID="updPanelTeste" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="rptProjetos" />
</Triggers>
<ContentTemplate>
...
</ContentTemplate>
</asp:UpdatePanel>
清单2
<asp:Repeater runat="server" ID="parentRepeater" OnItemCommand="parentRepeater_ItemCommand">
<ItemTemplate>
<div class="customFlexBox">
<div style="<%#Eval("MarginLeftText") %>">
<div style="<%#Eval("LeftBorder") %>">
<div style="<%#Eval("LeftBorderLast") %>" class="divContentHorizontal">
<div class="divContent">
<div class="divContainerBotoes">
<div class="botaoTooltip">
<asp:Button runat="server" CssClass="buttonAcoes" Text="+" ID="btnAddLiderado"
OnClientClick=<%# string.Format("test({0}, {1}); return false;", Eval("IdProjeto"), Eval("IdAssociado")) %>
/>
</div>
</div>
</div>
</div>
<asp:Repeater runat="server" ID="ChildRepeater" OnItemDataBound="mainRepeater_ItemDataBound" Visible="false">
</asp:Repeater>
<asp:Repeater runat="server" ID="NovoAvaliadoRepeater" Visible="false">
</asp:Repeater>
</div>
</div>
</div>
</ItemTemplate>
</asp:Repeater>
列表2上按钮的Java脚本
function test(IdProjeto, IdAssociado) {
document.getElementById('<%=txtLiderDummy.ClientID%>').value = -1;
document.getElementById('<%=txtLiderDummy.ClientID%>').value = IdAssociado;
document.getElementById('<%=txtDummy.ClientID%>').value = -1;
document.getElementById('<%=txtDummy.ClientID%>').value = IdProjeto;
document.getElementById('<%=txtDummy.ClientID%>').trigger('OnTextChanged');
__doPostBack("<%=updPanelTeste.UniqueID %>", "");
我尝试了所有的回发配置和所有的更新模式,但仍然是相同的行为。
1条答案
按热度按时间cuxqih211#
重复列表(列表1)具有带OnClick调用的按钮。按下这些按钮将调用代码隐藏方法并更新更新面板
不,不太喜欢!!!!
您有一个回发,此时整个页面被发送到服务器。您现在可以自由更新ANY和ALL控件,包括更新面板中的控件。
所以,术语“更新更新面板”在这个时间点并不重要,是一个100%无用的上下文。
你正在更新页面上的一些东西。一个完整的回发并不关心,也不重要,也没有任何上下文的一些更新面板。
所以,我们有一个按钮,页面回发,然后你只是哦,所以碰巧更新更新面板内的一些控件-但你可以自由地更新页面上的任何和所有控件,包括那些在UP。
好了,现在上面已经清楚了。
更新面板包含另一个具有更多按钮的列表(列表2),现在具有OnClientClick调用。按列表2的按钮会向列表2添加新行
好的,但是LIST 2已经有一些数据了吗?LIST 2是如何开始的?它是从没有值开始的吗?或者你在页面加载中有一些代码来设置这个列表2吗?
接下来,你为什么要用扳机
UP中的任何和所有按钮将触发并回发该面板。
当回发发生时,触发FULL页面生命周期STILL,并且页面加载事件将在UP中的任何按钮代码运行之前触发。
UP中的按钮代码只能修改UP中的控件和值等内容。代码不能获取/使用/抓取/享受其他控件的值,也不能修改它们(你可以尝试,但你看不到变化)。
这通常意味着页面加载事件有一些代码要设置或加载LIST 2。但是,由于它每次都为任何回发和任何按钮单击(包括UP中的按钮)运行,因此如果该代码有设置LIST 2的任务,那么每次都会看到更改丢失。
那么,会发生什么:
现在,如果再次单击,则:
同样,这意味着您只会看到1行,因为页面加载事件每次也会运行,并且在UP中的按钮代码之前运行。
因此,这意味着/建议您需要在页面加载事件中使用所有SUPER DUPER important isPostBack测试/检查。
在我最近创建的200多个网页中,如果你不遵循以下建议,没有一个能正常工作:这个建议是把你在页面加载中的设置代码只在第一次运行。
因此,您需要:
因此,现在当您单击UP面板中的按钮并向repeater添加一行时,您将看到该行。
但是,您没有显示如何向repeater添加行,并且由于它是数据绑定的,因此您必须
a)将行添加到数据源,重新拉取数据源并重新绑定中继器。
B)将LIST 2数据源持久化在会话或视图状态中,并添加到该数据表/对象,然后再次重新绑定到中继器(或列表2)
请记住,页面加载事件和回发确实发生在使用更新面板时(本文中的UP)。
它可能看起来像,似乎网页没有回发,但它确实!!
这就是我们所说的部分页面回发,这里不要搞错,页面加载事件触发,整个页面生命周期过程也运行。唯一的区别是只有UP被回发到服务器,因此按钮和代码只能修改UP内部的控件。
此外,如果您只想触发那个UP,那么使用js和UP内部的一个按钮(带有click方法)来代替尝试的__DoPostBack。
例如:
或者,如果你不标记按钮clientidmode,那么这个: