Rebinding sự kiện trong jQuery sau khi cập nhật Ajax (updatepanel)


80

Tôi có một số yếu tố đầu vào và tùy chọn trên trang của mình, mỗi phần tử (hầu như) đều có một sự kiện đính kèm để cập nhật một số văn bản trên trang khi chúng thay đổi. Tôi sử dụng jQuery thực sự rất tuyệt :)

Tôi cũng sử dụng khung công tác Microsofts Ajax , sử dụng UpdatePanel. Lý do tại sao tôi làm điều đó là các phần tử nhất định được tạo trên trang dựa trên một số logic phía máy chủ. Tôi thực sự không muốn giải thích lý do tại sao tôi sử dụng UpdatePanel - ngay cả khi nó có thể (nó có thể với một số nỗ lực) được viết lại để chỉ sử dụng jQuery Tôi vẫn muốn UpdatePanel đó.

Bạn có thể đoán ra điều đó - sau khi tôi đăng lại trên UpdatePanel, các sự kiện jQuery sẽ ngừng hoạt động. Tôi thực sự đã mong đợi điều này, vì "postback" không thực sự là một postback mới nên mã của tôi trong document.ready liên kết các sự kiện sẽ không được kích hoạt nữa. Tôi cũng xác nhận nghi ngờ của mình bằng cách đọc nó trong thư viện trợ giúp jQuery.

Dù sao thì tôi vẫn còn vấn đề về việc gắn lại các điều khiển của mình sau khi UpdatePanel cập nhật xong DOM . Tôi tốt nhất cần một giải pháp không yêu cầu thêm nhiều tệp .js (jQuery plug-in) vào trang nhưng một cái gì đó đơn giản như có thể bắt được 'cập nhật sau' của UpdatePanel, nơi tôi có thể gọi phương thức của mình để gắn kết lại tất cả các phần tử biểu mẫu .


Điều này rất giống với câu hỏi này: stackoverflow.com/questions/256195/…
Dan Herbert,

Câu trả lời:


85

Vì bạn đang sử dụng ASP.NET AJAX, bạn sẽ có quyền truy cập vào pageLoadtrình xử lý sự kiện, được gọi mỗi khi trang đăng lại, có thể là toàn bộ hoặc một phần từ UpdatePanel. Bạn chỉ cần đưa chức năng vào trang của mình, không cần nối.

function pageLoad(sender, args)
{
   if (args.get_isPartialLoad())
   {
       //Specific code for partial postbacks can go in here.
   }
}

1
Không sao - đó chỉ là một cách để làm việc đó btw. Nếu bạn cần sự linh hoạt hơn, hãy xem sự kiện endRequest trên lớp PageRequestManager.
Phil Jenkins

Tuyệt vời! Tôi đã thay thế jquery $ (document) của mình .ready bằng pageLoad của bạn (không có khối if) và nó đã giải quyết được vấn đề của tôi!
Chris

10
Thận trọng: chỉ một hàm "pageLoad" thực thi trên trang - hàm cuối cùng được xác định. Vì vậy, nếu các hành động cần được thực thi nằm trên các điều khiển khác nhau - có nhiều cách dễ dàng hơn để đạt được hành vi cần thiết - như "Sys.Application.add_load".
Paulius

23

Hoặc bạn có thể kiểm tra chức năng trực tiếp mới nhất của jQuery thông qua on()phương pháp này.


Đây là giải pháp tốt nhất cho tôi, vì phần lớn đánh dấu jQuery của tôi được gói gọn bên trong một số điều khiển của người dùng trên trang.
Kyle B.

1
bạn có thể đăng ví dụ với datepicker không?
Perica Zivkovic

Tôi chỉ sử dụng "on" để liên kết với danh sách thả xuống bên trong một bảng điều khiển không kích hoạt bài đăng không đồng bộ. Nó KHÔNG hoạt động cho đến khi, tôi cũng bao gồm câu trả lời ở trên của @Phil Jenkins. Tôi không chắc liệu nó có tạo ra sự khác biệt hay không nếu đó là một bài đăng không đồng bộ hoặc bài đăng đầy đủ trở lại, nhưng trên. chất kết dính đã không xử lý nó sau khi bài đăng trở lại.
Casey

22
Sys.Application.add_load(initSomething);
function initSomething()
{
  // will execute on load plus on every UpdatePanel postback
}

14

Kể từ jQuery 1.7, cách được khuyến nghị để làm điều này là sử dụng cú pháp .on () của jQuery .

Tuy nhiên, hãy đảm bảo rằng bạn thiết lập sự kiện trên đối tượng tài liệu , không phải bản thân đối tượng DOM. Ví dụ: điều này sẽ bị hỏng sau khi đăng lại UpdatePanel :

$(':input').on('change', function() {...});

... bởi vì ': input' đã được viết lại. Làm điều này thay thế:

$(document).on('change', ':input', function() {...});

Miễn là tài liệu còn xung quanh, bất kỳ đầu vào nào (bao gồm cả những đầu vào từ các bản cập nhật UpdatePanel) sẽ kích hoạt trình xử lý thay đổi.


Tuyệt vời ! (tài liệu) hoạt động đáng yêu bằng cách sử dụng .... $ (tài liệu) .on ('click', '# tagsAdd', function () bất kể tôi có bao nhiêu bảng cập nhật để chia nhỏ nội dung của trang :) Thx
Martin Sansone - MiOEE

9

Sử dụng mã sau

Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(pageLoaded);

function pageLoaded(sender, args) {
    var updatedPanels = args.get_panelsUpdated();
    // check if Main Panel was updated 
    for (idx = 0; idx < updatedPanels.length; idx++) {
        if (updatedPanels[idx].id == "<%=upMain.ID %>") {
            rebindEventsForMainPanel();
            break;
        }
    }
}

8

Bạn có thể sử dụng jQuery và ủy quyền sự kiện. Về cơ bản móc các sự kiện vào vùng chứa thay vì mọi phần tử và truy vấn event.target và chạy tập lệnh dựa trên đó.

Nó có nhiều lợi ích trong đó bạn giảm nhiễu mã (không cần phải rebind). Nó cũng dễ dàng hơn trên bộ nhớ trình duyệt (ít sự kiện bị ràng buộc trong DOM hơn.)

Ví dụ nhanh ở đây .

jQuery plugin để ủy quyền sự kiện dễ dàng.

Tái bút: Tôi chắc chắn 99% ủy quyền sẽ nằm trong lõi jQuery ở bản phát hành tiếp theo.


5

Sử dụng mã sau, Bạn cần phải xác thực điều khiển sẽ sử dụng bộ chuyển đổi dữ liệu:

    <script type="text/javascript" language="javascript">

         Sys.WebForms.PageRequestManager.getInstance().add_endRequest(addDataPicker); 
         function addDataPicker(sender, args)
         {
            var fchFacturacion = document.getElementById('<%= txtFechaFacturacion.ClientID %>');
            if (fchFacturacion != null) {
               $(fchFacturacion).datepicker({ onSelect: function () { }, changeMonth: true, changeYear: true, showOn: 'button', buttonImage: '../Imagenes/calendar.gif', buttonImageOnly: true});}
         } 

    </script>

     <asp:UpdatePanel ID="upEjem" runat="server" UpdateMode="Conditional">
       <ContentTemplate>
              <div id="div1" runat="server" visible="false">
                  <input type="text" id="txtFechaFacturacion" 
                      name="txtFechaFacturacion" visible="true"
                      readonly="readonly" runat="server" />
              </div>
       </ContentTemplate>
     </asp:UpdatePanel>

4

         <script type="text/javascript">
             function pageLoad() {

                 if (Sys.WebForms.PageRequestManager.getInstance().get_isInAsyncPostBack()) {


       }

            </script>

        </ContentTemplate>
    </asp:UpdatePanel>

vào "if", bạn có thể đặt mã mà bạn cần thực thi mỗi khi bảng cập nhật thực hiện AsyncPostBack.


2

Liên kết các sự kiện của bạn bằng phương pháp 'trực tiếp' mới của jQuery. Nó sẽ liên kết các sự kiện với tất cả các yếu tố hiện tại của bạn và tất cả các yếu tố trong tương lai. Cha ching! :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.