2012-06-23 29 views
9

Tôi có ấn tượng rằng một điều khiển trong UpdatePanel lồng nhau sẽ làm cho UpdatePanel ở mức cao nhất làm mới (do đó làm mới cả UpdatePanels) vì bất kỳ sự kiện nào trên điều khiển hoạt động như một trình kích hoạt "ẩn". Đúng không?Cập nhật lồng nhauPanel khiến phụ huynh đăng lại?

Tôi đã cố gắng để dây một cái gì đó như thế này Up-

UserControl 

    Parent UpdatePanel 

    "Show" button 

     ASP:Panel 

     Dynamically added UserControls, each with UpdatePanels 

Khi nút Show được nhấp, ASP: Bảng điều chỉnh trở nên rõ ràng và bắt đầu thêm UserControls để tự động, dựa trên một số back-end logic.

Mỗi điều khiển được thêm động (từ nay trở đi: UserControls) có các nút và liên kết hỗ trợ Atlas riêng, vì vậy chúng cũng có UpdatePanels. Hiện tại khi tôi nhấp vào liên kết trong một trong các UserControls, toàn bộ nội dung của ASP: Bảng điều khiển biến mất, như thể nó đang được hiển thị lại. Tất cả các điều khiển được thêm động của tôi đều biến mất và không có sự kiện nhấp chuột nào của họ bị bắt trong trình gỡ lỗi.

Tôi giả định điều đang xảy ra ở đây là các điều khiển nằm trong các bảng cập nhật lồng nhau khiến cho UpdatePanel gốc đăng lại vì chúng kích hoạt trình kích hoạt "ẩn". Có cách nào cho UserControls của tôi để hoạt động độc lập và không gây rối với ASP: Bảng điều khiển có chứa chúng?

Nếu không, tôi nên theo đuổi chiến lược nào ở đây? Nếu tôi phải render lại toàn bộ ASP: Panel mỗi lần một sự kiện xảy ra trên một trong những UserControls (có thể là nhiều), điều đó có nghĩa là tôi sẽ phải tạo lại UserControls, điều này cần một chút nỗ lực để tạo ra. Tôi cũng sẽ phải bảo tồn một số loại trạng thái xem để tạo lại chúng. Tôi hơi mới với ASP.NET và có vẻ đáng sợ. Tôi muốn không bao giờ làm mới UserControl đầu trang và ASP: Panel nếu tôi có thể tránh nó, và để cho mỗi lửa UserControls được thêm động và xử lý các sự kiện của riêng họ một cách không đồng bộ.

CHỈNH SỬA: Thay vì thêm các điều khiển động, tôi đã thêm chúng vào đánh dấu (không phải là giải pháp xấu). Vì vậy, đã thoát khỏi các điều khiển biến mất vấn đề, bởi vì bây giờ các điều khiển không được thêm động nhưng thay vào đó tồn tại trong đánh dấu. Nhưng vẫn còn phụ huynh UpdatePanel đăng là một hit hiệu suất lớn, bởi vì tất cả các UserControls đang nhận được đăng thay vì một. Làm cách nào để tôi chỉ tạo một lần đăng nhập UserControl? Ngoài ra, tôi muốn biết làm thế nào để thoát khỏi vấn đề kiểm soát biến mất nếu được thêm động?

Trả lời

14

Trước hết, hãy nhớ: UpdatePanels không thay đổi vòng đời của trang.

Tất cả cây điều khiển (bao gồm cả UpdatePanels) phải được tạo lại giống như vòng đời bình thường. UpdatePanels đảm bảo rằng chỉ một phần của chế độ xem được hiển thị (HTML) được trả về. Xóa tất cả UpdatePanels phải dẫn đến hành vi tương tự , ngoại trừ toàn bộ đăng lại. Ví dụ, chỉ có HTML đại diện cho một UpdatePanel lồng nhau (có lẽ vì dữ liệu thay đổi) có thể được gửi trở lại trong phản hồi XHR.

Để nhận được "đúng" AJAX, hãy xem xét Phương pháp trang. Ngoài ra, DevExpress (và có lẽ Telerik và những người khác?) Cung cấp hình thức riêng của họ "Callback Panels", tương tự như UpdatePanels, nhưng có thể bỏ qua các phần của vòng đời (và, kết quả là thường không hỗ trợ mô hình ViewState hoặc có thể giới thiệu những câu hỏi riêng của họ).


Trong khi không hiểu ở trên là nguyên nhân phần nhiều cho các điều khiển "biến mất", đây là quy tắc của tôi: Không Hãy để [Nested] UpdatePanels làm việc "Tự động".

Trường hợp cạnh có điều khiển động và UpdatePanels lồng nhau sẽ gặp phải. Có thể có một cách hay để xử lý việc này, nhưng tôi đã thất bại trong nhiều lần thử khác nhau.

Thay vào đó, cho mỗi bảng cập nhật, chạy với:

UpdateMode="Conditional" 
ChildrenAsTriggers="False" 

Với UpdateMode "có điều kiện", chắc chắn phải tự xác định việc kiểm soát Trigger hoặc gọi panel.Update() (mặc dù điều này khó dây Control) theo yêu cầu. Tùy theo nhu cầu ChildrenAsTriggers="True" cũng có thể hoạt động. Điều quan trọng là UpdateMode không phải là "Luôn luôn" là mặc định.

Sau khi chuyển sang phương pháp này, tôi không gặp vấn đề gì - tốt, hầu như không có - với UpdatePanels lồng nhau.

Mã hóa vui vẻ!


Nếu trang không làm một cách chính xác nơi Rendering một phần (trong ScriptManager) bị vô hiệu hóa (ví dụ như tất cả các yêu cầu có đầy đủ đăng lại) thì không có lý do gì để mong đợi/tin rằng nó sẽ làm việc một cách chính xác với UpdatePanels.

Có những lúc nó được bảo đảm "lừa gạt" các lần tính toán đắt tiền trong cây điều khiển đối với các điều khiển sẽ không được hiển thị lại. Tuy nhiên, tôi sẽ xem xét các trường hợp nâng cao này chỉ nên được thực hiện khi phân tích hiệu suất cho thấy có nhu cầu cụ thể.

0

Tôi gặp sự cố tương tự với điều khiển ajax nặng Gridview và một trang HTML có nhiều số UpdatePanels, một số lồng nhau, một số thì không.

Mất hơn 3 tuần thử nghiệm và báo lỗi, đọc, thử nghiệm, gỡ lỗi và tạo mẫu để cuối cùng giải quyết tất cả các bài đăng và một phần postback.

Tuy nhiên, tôi đã chú ý đến một mô hình phù hợp với tôi.

Giống như câu trả lời của người dùng trên, hãy đảm bảo UpdatePanels của bạn được đặt Điều kiện và chỉ cụ thể asp:PostBackTrigger trên điều khiển cuối cùng hoặc quyết định mà bạn muốn trang đăng lại hoàn toàn. Tôi luôn sử dụng asp:AsyncPostBackTrigger nơi có thể.

Ví dụ: nếu bạn đang sử dụng UpdatePanels bên trong GridView và bạn muốn cửa sổ bật lên bên trong ô của hàng Gridview, thì bạn cần sử dụng UpdatePanel lồng nhau.

tức

<asp:TemplateField HeaderText="Actions &amp; Communications"> 
    <ItemTemplate> 
     <asp:UpdatePanel ID="upAction1" runat="server" UpdateMode="Conditional"> 
      <Triggers> 
       <asp:AsyncPostBackTrigger ControlID="btnActionOK" /> 
      </Triggers> 
      <ContentTemplate> 
... 
... 
          <ajaxToolkit:ModalPopupExtender ID="ajaxMPE" runat="server" 
           BackgroundCssClass="modalBackground" 
           PopupControlID="upAction2" 
           TargetControlID="btnADDaction"> 
          </ajaxToolkit:ModalPopupExtender> 
          <asp:UpdatePanel ID="upAction2" runat="server" UpdateMode="Conditional"> 
           <ContentTemplate> 
            <asp:Panel ID="pnlACTION" runat="server" CssClass="pnlACTION"> 
             <div id="divHDR"> 
              <asp:Label ID="lblActionHdr" runat="server">** header **</asp:Label> 
             </div> 
             <div id="divBOD"> 
              <table style="width: 98%; text-align:left"> 
               <tr> 
                <td colspan="2"> 
                Please enter action item:<br /> 
                 <asp:TextBox ID="txtAction" runat="server" ValidationGroup="vgAction" TextMode="MultiLine" Rows="3" Width="98%"></asp:TextBox> 
                 <asp:RequiredFieldValidator ID="rfvAction" runat="server" ControlToValidate="txtAction" ValidationGroup="vgAction" 
                  ErrorMessage="* Required" SetFocusOnError="True"></asp:RequiredFieldValidator></td> 
               </tr> 
               <tr> 
                <td colspan="2"> 
                Select staff assigned to this task:<br /> 
                 <asp:DropDownList ID="ddlActionStaff" runat="server" AppendDataBoundItems="true" ValidationGroup="vgAction" /> 
                 <asp:RequiredFieldValidator ID="rfvStaff" runat="server" ControlToValidate="ddlActionStaff" InitialValue="0" ValidationGroup="vgAction" 
                  ErrorMessage="* Required" SetFocusOnError="True" Width="98%"></asp:RequiredFieldValidator></td> 
               </tr> 
               <tr> 
                <td colspan="2" style="text-align: center"> 
                  <asp:Button ID="btnActionOK" runat="server" Text="OK" OnClick="btnActionOK_Click" ValidationGroup="vgAction" CausesValidation="false" /> 
                  <asp:Button ID="btnActionCANCEL" runat="server" Text="CANCEL" OnClick="btnActionCANCEL_Click" ValidationGroup="vgAction" CausesValidation="false" /> 
                </td> 
               </tr> 
              </table> 
             </div> 
            </asp:Panel> 
           </ContentTemplate> 
          </asp:UpdatePanel> 
         </td> 
        </tr> 
       </table> 
       <asp:SqlDataSource ID="sdsTETactions" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>" 
... 
... 
       </asp:SqlDataSource> 
      </ContentTemplate> 
     </asp:UpdatePanel> 
    </ItemTemplate> 
    <ItemStyle HorizontalAlign="Center" /> 
</asp:TemplateField> 

Chú ý một vài điều ở đây:

  • Các ModalPopupExtender không đề cập đến các nút OK và Cancel.Điều này là bởi vì tôi muốn họ kích hoạt một phần postback cho máy chủ (code-behind)
  • UpdatePanel lồng nhau (upAction2) hoàn toàn là buộc một phần postback trên bảng điều khiển chỉ (pnlAction)! Do đó điều này buộc việc xác thực dữ liệu kích hoạt để hoạt động và giữ cho bảng điều khiển mở nếu người dùng không cung cấp dữ liệu trong trình xác nhận requiredfield
  • UpdatePanel chính (upAction1) điều khiển toàn bộ lô và giữ tất cả các postback được giữ trong bảng đó và KHÔNG ảnh hưởng đến GridView (không hiển thị hoàn toàn).

Có một bài viết tuyệt vời here, giải thích tốt hơn.

Tôi hy vọng điều này sẽ giúp ai đó

Các vấn đề liên quan