/ / Веб-форми ASP.NET бентежать поведінку зворотного зворотного зв'язку - javascript, asp.net, веб-форми

Веб-форми ASP.NET незрозумілі поведінки після зворотного зв'язку - javascript, asp.net, веб-форми

Я створив невеликий скрипт для збереження сфокусованого елемента під час асинхронної зворотної передачі, і він чудово працює окрім при вкладці через елементи керування, сформовані всередині asp: Repeater, де a повний зворотний зв’язок спрацьовує з якоїсь таємничої причини. Ось короткий зразок для роботи:

<%@ Page Language="C#" EnableEventValidation="false" %>
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<script runat="server">
public IEnumerable<int> Measurements_GetData()
{
return new[] { 123, 328, 1099 };
}
</script>
</head>
<body>
<form method="post" runat="server">
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<h1>OK</h1>
<div>
<asp:TextBox ID="Measurement1" runat="server" Text="123" AutoPostBack="true"  />
</div>

<div>
<asp:TextBox ID="TextBox1" runat="server" Text="328" AutoPostBack="true" />
</div>

<div>
<asp:TextBox ID="TextBox2" runat="server" Text="1099" AutoPostBack="true" />
</div>

<h1>Not OK</h1>
<asp:Repeater ID="Measurements" runat="server" SelectMethod="Measurements_GetData" ItemType="System.Int32">
<ItemTemplate>
<div>
<asp:TextBox ID="Measurement" runat="server" AutoPostBack="true" Text="<%# Item %>" />
</div>
</ItemTemplate>
</asp:Repeater>
</ContentTemplate>
</asp:UpdatePanel>
</form>
<script type="text/javascript">
(function () {
var focusedElementId = "";
var prm = Sys.WebForms.PageRequestManager.getInstance();

prm.add_pageLoaded(function (source, args) {
// re-focus element, if any selected prior to postback
if (focusedElementId !== "") {
document.getElementById(focusedElementId).focus();
console.log("focus:" + focusedElementId);
}
});

prm.add_pageLoading(function (source, args) {
var fe = document.activeElement;
focusedElementId = fe !== null ? fe.id : "";
});
})();
</script>
</body>
</html>

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

Тепер, якщо ви переглядаєте консоль JS і натискаєте наперший введення тексту в розмітці ретранслятора (розділ «Не в порядку»), змініть потім вкладку, змініть потім вкладку знову, ви можете бачити, що фокус втрачається на останньому елементі керування, оскільки спрацьовує повний зворотний зворотний зв'язок (консоль JS очищена).

Що тут відбувається? Здається, це повинна бути помилка веб-форм, інакше я не можу її зрозуміти. Якщо це помилка, чи є спосіб вирішення проблеми?

Відповіді:

1 для відповіді № 1

Як я підозрював, це відома проблема веб-форм ASP.NET. Це спричинено змінами ClientIDMode в ASP.NET 4.0. MS розміщено деякі обхідні шляхи тут.

Якщо вас не хвилює згенеровані ідентифікатори елементів керування, видається найпростішим рішенням повернення до поведінки pre-ASP.NET 4.0 шляхом встановлення:

<pages ClientIDMode="AutoID" /

в web.config.


0 для відповіді № 2

Це схоже не на помилку, а на ваш JavaScriptфункція чомусь є причиною PostBack. Якщо видалити його повністю, TextBoxes поводяться так, як слід. Ймовірно, існує невідповідність між TextBoxes, прив'язаними вашим сценарієм (який запускається лише при першій завантаженні сторінки), і тими, які відтворюються всередині Repeater після асинхронної зворотної передачі.

Якщо ви зареєструєте всі TextBox для Async PostBack, вони знову запрацюють.

protected void Page_Load(object sender, EventArgs e)
{
foreach (RepeaterItem item in Measurements.Items)
{
TextBox tb = item.FindControl("Measurement") as TextBox;
ScriptManager.GetCurrent(Page).RegisterAsyncPostBackControl(tb);
}
}