asp.net 回发只工作一次,然后消失

33qvvth1  于 2023-03-09  发布在  .NET
关注(0)|答案(1)|浏览(175)

场景:

我有一个包含当前操作顺序的网站页面:

  • 转发器列表(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 %>", "");

我尝试了所有的回发配置和所有的更新模式,但仍然是相同的行为。

cuxqih21

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的任务,那么每次都会看到更改丢失。
那么,会发生什么:

page load event runs - set up LIST 2
  your button code in UP runs - adds one row, you see 1 row.

现在,如果再次单击,则:

page load event runs - set up LIST 2
  your button code in UP runs - adds one row, you see 1 row.

同样,这意味着您只会看到1行,因为页面加载事件每次也会运行,并且在UP中的按钮代码之前运行。
因此,这意味着/建议您需要在页面加载事件中使用所有SUPER DUPER important isPostBack测试/检查。
在我最近创建的200多个网页中,如果你不遵循以下建议,没有一个能正常工作:这个建议是把你在页面加载中的设置代码只在第一次运行。
因此,您需要:

if (!isPostBack) 
 {
     // your setup code here, load repeater code here
 }

因此,现在当您单击UP面板中的按钮并向repeater添加一行时,您将看到该行。
但是,您没有显示如何向repeater添加行,并且由于它是数据绑定的,因此您必须
a)将行添加到数据源,重新拉取数据源并重新绑定中继器。
B)将LIST 2数据源持久化在会话或视图状态中,并添加到该数据表/对象,然后再次重新绑定到中继器(或列表2)
请记住,页面加载事件和回发确实发生在使用更新面板时(本文中的UP)。
它可能看起来像,似乎网页没有回发,但它确实!!
这就是我们所说的部分页面回发,这里不要搞错,页面加载事件触发,整个页面生命周期过程也运行。唯一的区别是只有UP被回发到服务器,因此按钮和代码只能修改UP内部的控件。
此外,如果您只想触发那个UP,那么使用js和UP内部的一个按钮(带有click方法)来代替尝试的__DoPostBack。
例如:

$('#MyButtonInUP').click()

或者,如果你不标记按钮clientidmode,那么这个:

$('#<%= MyButtonInUP.ClientID %>').click()

相关问题