Đăng lại ASP.NET với JavaScript


80

Tôi có một số divs nhỏ đang sử dụng jQuerycó thể kéo. Những thứ này divđược đặt trong một UpdatePanelvà trên dragstop, tôi sử dụng _doPostBack()hàm JavaScript, nơi tôi trích xuất thông tin cần thiết từ biểu mẫu của trang.

Vấn đề của tôi là khi tôi gọi hàm này, toàn bộ trang được tải lại, nhưng tôi chỉ muốn bảng cập nhật được tải lại.


Các div của bạn có một ID duy nhất không?
Nathan Taylor,

Câu trả lời:


226

Đây là một giải pháp hoàn chỉnh

Toàn bộ thẻ biểu mẫu của trang asp.net

<form id="form1" runat="server">
    <asp:LinkButton ID="LinkButton1" runat="server" /> <%-- included to force __doPostBack javascript function to be rendered --%>

    <input type="button" id="Button45" name="Button45" onclick="javascript:__doPostBack('ButtonA','')" value="clicking this will run ButtonA.Click Event Handler" /><br /><br />
    <input type="button" id="Button46" name="Button46" onclick="javascript:__doPostBack('ButtonB','')" value="clicking this will run ButtonB.Click Event Handler" /><br /><br />

    <asp:Button runat="server" ID="ButtonA" ClientIDMode="Static" Text="ButtonA" /><br /><br />
    <asp:Button runat="server" ID="ButtonB" ClientIDMode="Static" Text="ButtonB" />
</form>

Toàn bộ nội dung của lớp mã phía sau của trang

Private Sub ButtonA_Click(sender As Object, e As System.EventArgs) Handles ButtonA.Click
    Response.Write("You ran the ButtonA click event")
End Sub

Private Sub ButtonB_Click(sender As Object, e As System.EventArgs) Handles ButtonB.Click
    Response.Write("You ran the ButtonB click event")
End Sub
  • LinkButton được bao gồm để đảm bảo rằng hàm javascript __doPostBack được hiển thị cho máy khách. Chỉ cần có các điều khiển Nút sẽ không làm cho hàm __doPostBack này được hiển thị. Chức năng này sẽ được hiển thị nhờ có nhiều điều khiển trên hầu hết các trang ASP.NET, vì vậy thường không cần một nút liên kết trống

Chuyện gì vậy?

Hai điều khiển đầu vào được hiển thị cho máy khách:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
  • __EVENTTARGET nhận đối số 1 của __doPostBack
  • __EVENTARGUMENT nhận đối số 2 của __doPostBack

Hàm __doPostBack được hiển thị như sau:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
  • Như bạn có thể thấy, nó chỉ định các giá trị cho các đầu vào ẩn.

Khi biểu mẫu gửi / đăng lại xảy ra:

  • Nếu bạn đã cung cấp UniqueID của Nút điều khiển máy chủ có trình xử lý nhấp chuột vào nút mà bạn muốn chạy ( javascript:__doPostBack('ButtonB','')thì trình xử lý nhấp vào nút cho nút đó sẽ được chạy.

Điều gì sẽ xảy ra nếu tôi không muốn chạy trình xử lý nhấp chuột mà muốn làm điều gì đó khác thay thế?

Bạn có thể chuyển bất cứ thứ gì bạn muốn làm đối số cho __doPostBack

Sau đó, bạn có thể phân tích các giá trị đầu vào ẩn và chạy mã cụ thể tương ứng:

If Request.Form("__EVENTTARGET") = "DoSomethingElse" Then
    Response.Write("Do Something else") 
End If

Ghi chú khác

  • Điều gì sẽ xảy ra nếu tôi không biết ID của điều khiển có trình xử lý nhấp chuột mà tôi muốn chạy?
    • Nếu nó không phải là chấp nhận được để thiết lập ClientIDMode="Static", sau đó bạn có thể làm một cái gì đó như thế này: __doPostBack('<%= myclientid.UniqueID %>', '').
    • Hoặc là: __doPostBack('<%= MYBUTTON.UniqueID %>','')
    • Thao tác này sẽ đưa id duy nhất của điều khiển vào javascript, nếu bạn muốn

47
+1 cho sự hoàn chỉnh. Loại câu trả lời tuyệt vời khiến tôi yêu thích StackOverflow.
Manitra Andriamitondra

3
Đây là một trong những lời giải thích hay nhất mà tôi từng xem cho __doPostBack () .. +10 cho điều này!
GuruC

1
@BrianWebster, Rất cảm ơn vì bài đăng chi tiết của bạn. Tôi có thể đề nghị bất kỳ ai vẫn đang sử dụng ASP.NET 3.5 trở xuống sử dụng C # thay vì VB.NET thay đổi hai dòng cuối cùng trong tệp .aspx thành như sau không? <asp: Button runat = "server" ID = "ButtonA" Text = "ButtonA" OnClick = "ButtonA_Click" /> <br /> <br /> <asp: Button runat = "server" ID = "ButtonB" Text = "ButtonB" OnClick = "ButtonB_Click" />
yangli.liy

1
Đây là một giải pháp rất hữu ích. Nếu bạn đang sử dụng các trang chính, id của các nút sẽ bị xáo trộn một chút. Xem câu trả lời của user489998 bên dưới để được trợ giúp lấy id chính xác cho bài đăng lại.
DCastenholz

1
@BrianWebster Thật sự hiếm khi ai đó có thể cung cấp giải pháp hoàn chỉnh cho vấn đề của ai đó VÀ cung cấp các giải pháp thay thế thích hợp cho những sai lệch tiềm ẩn.
GoldBishop

15

Per Phairoh: Sử dụng điều này trong Trang / Thành phần chỉ trong trường hợp tên bảng điều khiển thay đổi

<script type="text/javascript">
     <!--
     //must be global to be called by ExternalInterface
         function JSFunction() {
             __doPostBack('<%= myUpdatePanel.ClientID  %>', '');
         }
     -->
     </script>

9

Trong khi giải pháp của Phairoh về mặt lý thuyết có vẻ hợp lý, tôi cũng đã tìm ra một giải pháp khác cho vấn đề này. Bằng cách chuyển id UpdatePanels làm paramater (mục tiêu sự kiện) cho hàm doPostBack, bảng cập nhật sẽ đăng lại nhưng không đăng toàn bộ trang.

__doPostBack('myUpdatePanelId','')

* lưu ý: tham số thứ hai dành cho các args sự kiện bổ sung

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

CHỈNH SỬA: vì vậy có vẻ như lời khuyên này đã được đưa ra ở trên khi tôi đang gõ :)


2
Điều này sẽ hoạt động, và tôi đã làm điều gì đó tương tự trong một ứng dụng, nhưng nó thực sự không phải là một ý tưởng hay và tôi ghét rằng tôi đã phải làm điều đó khi tôi đã làm. Nếu tên bảng cập nhật của bạn thay đổi, nó sẽ bị hỏng. Nếu bạn đặt điều này vào bên trong điều khiển của người dùng, nó sẽ bị hỏng. Nếu bạn thêm một trang chủ, nó sẽ bị hỏng. Có nó hoạt động, nhưng nó khá mỏng manh. Ít nhất, hãy sử dụng thuộc tính ClientId của bảng cập nhật của bạn thay vì chuỗi tĩnh.
phairoh 20/08/09

9

Sử dụng __doPostBacktrực tiếp là sooooo những năm 2000. Bất kỳ ai viết mã WebForms vào năm 2018 đều sử dụng GetPostBackEventReference

(Mặc dù vậy, nghiêm túc hơn, thêm điều này làm câu trả lời cho sự đầy đủ. Sử dụng __doPostBacktrực tiếp là một phương pháp không tốt (tiền tố gạch dưới đơn thường biểu thị thành viên riêng tư và dấu kép biểu thị thành viên riêng phổ biến hơn), mặc dù nó có thể sẽ không thay đổi hoặc trở nên lỗi thời ở điều này điểm. Chúng tôi có một cơ chế được hỗ trợ đầy đủ trong ClientScriptManager.GetPostBackEventReference .)

Giả sử btnRefresh của bạn nằm trong UpdatePanel của chúng tôi và gây ra lỗi đăng lại, bạn có thể sử dụng GetPostBackEventReference như thế này ( cảm hứng ):

function RefreshGrid() {
    <%= ClientScript.GetPostBackEventReference(btnRefresh, String.Empty) %>;
}

Điều này hoạt động rất tốt. Trong tình huống của tôi, tôi có thể khai báo các điều khiển Target AJAX sẽ được làm mới khi btnRefresh được nhấp trong đánh dấu HTML. Bằng cách sử dụng này, nó làm cho nó cực kỳ đơn giản để thực hiện điều này với sự hỗ trợ cho AJAX.
DanielG

6

Nếu bất kỳ ai gặp sự cố với điều này (như tôi đã từng), bạn có thể lấy mã đăng lại cho một nút bằng cách thêm thuộc tính UseSubmitBehavior = "false" vào đó. Nếu bạn kiểm tra nguồn hiển thị của nút, bạn sẽ thấy javascript chính xác mà bạn cần để thực thi. Trong trường hợp của tôi, nó đang sử dụng tên của nút thay vì id.


Rất hữu ích khi sử dụng trang chủ.
DCastenholz

1
__doPostBack dường như luôn sử dụng tên của nút khi sử dụng các trang chính.
Dennis T - Phục hồi Monica -

2

Bạn đã thử chuyển id máy khách của bảng Cập nhật sang hàm __doPostBack chưa? Nhóm của tôi đã thực hiện việc này để làm mới bảng cập nhật và theo như tôi biết thì nó đã hoạt động.

__doPostBack(UpdatePanelClientID, '**Some String**');

1

Đầu tiên, không sử dụng bảng cập nhật. Chúng là thứ xấu xa thứ hai mà Microsoft từng tạo ra cho nhà phát triển web.

Thứ hai, nếu bạn phải sử dụng bảng cập nhật, hãy thử đặt thuộc tính UpdateMode thành Điều kiện. Sau đó, thêm trình kích hoạt vào điều khiển Asp: Ẩn mà bạn thêm vào trang. Gán sự kiện thay đổi làm trình kích hoạt. Trong sự kiện dragstop của bạn, hãy thay đổi giá trị của điều khiển ẩn.

Điều này chưa được kiểm tra, nhưng lý thuyết có vẻ đúng ... Nếu điều này không hiệu quả, bạn có thể thử điều tương tự với nút asp:, chỉ cần đặt kiểu hiển thị: không có trên đó và sử dụng sự kiện nhấp chuột thay vì sự kiện thay đổi.


7
điều xấu xa nhất đầu tiên mà microsoft tạo ra cho các nhà phát triển web là gì?
ErnieStings

2
kiểm soát đăng nhập phải khá cao trong danh sách đó.
kim3er 20-08-09

27
@ErnieCài đặt: IE6
phairoh

1
Bạn có thể giải thích điều gì khiến UpdatePanels trở thành thứ xấu xa không? Nếu đúng như vậy, tôi muốn đọc một số lý do tại sao và khi nào không sử dụng chúng. Cho đến nay, tôi chưa vấp phải bất kỳ vấn đề quan trọng nào với UpdatePanels.
Jan Kukacka

@JanKukacka Chúng là một bản tóm tắt kém của AJAX. Các kỹ năng bạn học được khi viết bảng cập nhật không trực tiếp chuyển sang việc có thể sử dụng AJAX đúng cách trong bất kỳ thứ gì bên ngoài ASP.NET Web Forms. UpdatePanels rất khó gỡ lỗi. Và nếu bạn bật ViewState, một lượng lớn dữ liệu được chuyển đến / từ máy chủ một cách không cần thiết, khiến băng thông của nó trở nên tốn kém. Học AJAX thích hợp (có lẽ với một số lớp trừu tượng nhẹ như jQuery) là một giải pháp tốt hơn nhiều khi bạn cần nói chuyện với máy chủ mà không thực hiện đăng lại.
thợ nề

1

Bạn không thể gọi _doPostBack()vì nó buộc phụ đề của biểu mẫu. Tại sao bạn không tắt tính năng PostBackbật UpdatePanel?


1
Một câu hỏi. Khi một div được kéo, _doPostBack được bạn gọi hay tự động bởi ASP.NET?
Alex Rodrigues

nó được gọi bởi tôi qua javascript
ErnieStings
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.