Зворотній зв’язок ASP.NET з JavaScript


81

У мене є кілька маленьких divs, які використовують jQueryперетягування. Вони divрозміщуються у UpdatePanel, а на dragstop я використовую функцію _doPostBack()JavaScript, де витягую необхідну інформацію з форми сторінки.

Моя проблема полягає в тому, що коли я викликаю цю функцію, вся сторінка перезавантажується, але я хочу лише перезавантажити панель оновлення.


Чи всі ваші divs мають унікальний ідентифікатор?
Натан Тейлор

Відповіді:


228

Ось повне рішення

Повний тег форми сторінки 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>

Весь зміст класу сторінки поза кодом

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, щоб переконатися, що функція __doPostBack javascript надається клієнту. Просто наявність кнопок управління не призведе до відображення цієї функції __doPostBack. Ця функція відображатиметься завдяки наявності різноманітних елементів керування на більшості сторінок ASP.NET, тому порожня кнопка посилання зазвичай не потрібна

Що відбувається?

Клієнту відображаються два елементи керування введенням:

<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
  • __EVENTTARGET отримує аргумент 1 з __doPostBack
  • __EVENTARGUMENT отримує аргумент 2 з __doPostBack

Функція __doPostBack відображається так:

function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
  • Як бачите, він призначає значення прихованим входам.

Коли форма подається / повертається:

  • Якщо ви надали унікальний ідентифікатор кнопки керування сервером, чий обробник клацання кнопки ви хочете запустити ( javascript:__doPostBack('ButtonB',''), тоді буде запущений обробник натискання кнопки для цієї кнопки.

Що робити, якщо я не хочу запускати обробник клацань, а хочу замість цього зробити щось інше?

Ви можете передати все, що хочете, як аргументи __doPostBack

Потім ви можете проаналізувати приховані вхідні значення і відповідно запустити конкретний код:

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

Інші примітки

  • Що робити, якщо я не знаю ідентифікатора елемента керування, чий обробник клацань я хочу запустити?
    • Якщо це не прийнятно для набору ClientIDMode="Static", то ви можете зробити що - щось на зразок цього: __doPostBack('<%= myclientid.UniqueID %>', '').
    • Або: __doPostBack('<%= MYBUTTON.UniqueID %>','')
    • Це вкаже унікальний ідентифікатор елемента керування в javascript, якщо ви цього забажаєте

48
+1 для повноти. Чудові відповіді, які змушують мене любити StackOverflow.
Манітра Андріамітондра

3
Це одне з найкращих пояснень, яке я коли-небудь стикався з __doPostBack () .. +10 за це!
GuruC

1
@BrianWebster, Велике спасибі за ваш докладний допис. Чи можу я запропонувати кожному, хто все ще користується ASP.NET 3.5 і нижче, використовуючи C # замість VB.NET, змінити останні два рядки у файлі .aspx на наступні? <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
Це дуже корисне рішення. Якщо ви використовуєте основні сторінки, ідентифікатор кнопок стає дещо незрозумілим. Дивіться відповідь користувача 489998 нижче, щоб отримати допомогу щодо отримання правильного ідентифікатора зворотного зворотного зв'язку.
DCastenholz,

1
@BrianWebster По-справжньому рідко хтось може надати повне рішення чиєїсь проблеми І надати відповідні альтернативи потенційним відхиленням.
GoldBishop 02

15

Per Phairoh: Використовуйте це в Сторінці / Компоненті на випадок зміни назви панелі

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

10

Хоча рішення Файроха здається теоретично обґрунтованим, я також знайшов інше рішення цієї проблеми. Передаючи ідентифікатор UpdatePanels як параметр (ціль події) для функції doPostBack, панель оновлення опублікує назад, але не всю сторінку.

__doPostBack('myUpdatePanelId','')

* примітка: другий параметр призначений для аргументів подій додавання

сподіваюся, це комусь допоможе!

РЕДАГУВАТИ: отже, ця сама порада була дана вище, коли я друкував :)


2
Це спрацює, і я зробив щось подібне в додатку, але це насправді не є гарною ідеєю, і я ненавиджу, що мені доводилося це робити, коли я це робив. Якщо ім’я вашої панелі оновлення коли-небудь змінюється, воно ламається. Якщо ви коли-небудь помістите це всередину елемента керування користувача, воно зламається. Якщо ви додасте головну сторінку, вона зламається. Так, це працює, але досить крихко. Принаймні, використовуйте властивість ClientId вашої панелі оновлення замість статичного рядка.
phairoh

9

Використання __doPostBackбезпосередньо оооооооо 2000-х років. Той, хто кодує WebForms у 2018 році, використовує GetPostBackEventReference

(Хоча більш серйозно, додавши це як відповідь на повноту. Використання __doPostBackбезпосередньо - це погана практика (префікс одинарного підкреслення зазвичай вказує на приватного члена, а подвійний - на більш універсального приватного члена), хоча він, мабуть, у цьому випадку не зміниться і не застаріє точка. У нас є повністю підтримуваний механізм у ClientScriptManager.GetPostBackEventReference .)

Припускаючи, що ваш btnRefresh знаходиться всередині нашого UpdatePanel і викликає зворотний зворотний зв’язок, ви можете використовувати GetPostBackEventReference таким чином ( натхнення ):

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

Це працює дуже добре. У моїй ситуації я можу оголосити, що елементи керування Target AJAX оновлюються при натисканні btnRefresh у розмітці HTML. Використовуючи це, це надзвичайно просто реалізувало це завдяки підтримці AJAX.
DanielG

6

Якщо у когось із цим виникають проблеми (як це було у мене), ви можете отримати код зворотного зв'язку для кнопки, додавши до неї атрибут UseSubmitBehavior = "false". Якщо ви вивчите відтворене джерело кнопки, ви побачите точний javascript, який вам потрібно виконати. У моєму випадку це використовувало назву кнопки, а не ідентифікатор.


Дуже корисно при використанні головних сторінок.
DCastenholz

1
Здається, __doPostBack завжди використовує назву кнопки під час використання основних сторінок.
Денніс Т - відновити Моніку -

2

Ви пробували передавати ідентифікатор клієнта панелі оновлення функції __doPostBack? Моя команда зробила це, щоб оновити панель оновлення, і, наскільки я знаю, це спрацювало.

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

1

По-перше, не використовуйте панелі оновлення. Вони є другою за злом річчю, яку Microsoft коли-небудь створювала для веб-розробника.

По-друге, якщо вам потрібно використовувати панелі оновлення, спробуйте встановити для властивості UpdateMode умовний. Потім додайте тригер до елемента керування Asp: Hidden, який ви додаєте на сторінку. Призначити подію зміни як тригер. У події перетягування змініть значення прихованого елемента керування.

Це не перевірено, але теорія здається обґрунтованою ... Якщо це не спрацює, ви можете спробувати те ж саме за допомогою кнопки asp: просто встановіть на ньому стиль display: none і використовуйте подію click замість події зміни.


7
що перше найзлобніше, що створив Microsoft для веб-розробників?
ErnieStings

2
контроль входу повинен бути досить високим в цьому списку.
kim3er

1
Чи можете ви пояснити, що робить UpdatePanels настільки злим? Якщо це так, я хотів би прочитати кілька причин, чому і коли не використовувати їх. Дотепер я не стикався з якимись вирішальними проблемами з UpdatePanels.
Jan Kukacka

@JanKukacka Вони погана абстракція від AJAX. Навички, які ви вивчаєте при написанні панелей оновлень, безпосередньо не означають можливості належного використання AJAX у будь-чому, що не входить до веб-форм ASP.NET. Панелі UpdatePanel важко налагодити. І якщо у вас увімкнено ViewState, велика кількість даних передається на сервер / з сервера без потреби, роблячи інтенсивною пропускну здатність. Навчання правильному AJAX (можливо, з яким-небудь легким шаром абстракції, таким як jQuery), є набагато кращим рішенням, коли вам потрібно поговорити з сервером, не виконуючи зворотну зворотну передачу.
муляр

1

Ви не можете зателефонувати, _doPostBack()оскільки це змушує подати форму. Чому б вам не відключити PostBackувімкнене UpdatePanel?


1
Питання. Коли div перетягується, _doPostBack викликається вами або автоматично ASP.NET?
Алекс Родрігес,

це викликано мною через javascript
ErnieStings
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.