UpdatePanel иногда не обновляет данные. Иногда бывают долгие задержки
У меня есть UpdatePanel
это имеет другой Panel
внутри имитировать простое всплывающее окно.
Внутри Panel
У меня есть таблица HTML, с несколькими строками и несколькими столбцами, и GridView
в один ряд и DetailsView
дальше.
Есть также кнопка ОТПРАВИТЬ и ОТМЕНА на стороне таблицы HTML.
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:PostBackTrigger ControlID="ButtonSubmit" />
<asp:PostBackTrigger ControlID="ButtonCancel" />
</Triggers>
<ContentTemplate>
<asp:Panel ID="pnlRoomDetails" runat="server" CssClass="pnlDetail" Visible="false" Width="500px">
<table id="tblDetails" runat="server" style="width: 100%">
<tr style="height:26px;">
<td colspan="6" style="font-size: 12pt; color: yellow; font-family: Arial; background-color: blue;
text-align: center" valign="middle">
<strong>Room Allocation</strong></td>
</tr>
<tr>
<td colspan="1" style="text-align: left; vertical-align: middle; width: 128px; height: 24px;" valign="top">
<strong>
Room ID</strong></td>
<td colspan="3" style="width: 357px; text-align: left; vertical-align: middle; height: 24px;">
<asp:Label ID="lblRoomID" runat="server" Text="Label" Font-Bold="true"></asp:Label></td>
<td colspan="1" style="vertical-align: middle; width: 106px; height: 24px; text-align: left">
<strong>
Available?</strong></td>
<td colspan="1" style="vertical-align: middle; width: 120px; height: 24px; text-align: left">
<asp:CheckBox ID="cbStatus" runat="server" Width="98px" Enabled="False" /></td>
</tr>
<tr>
<td colspan="1" style="text-align: left; vertical-align: middle; width: 128px; height: 24px;" valign="top">
<strong>
Name</strong></td>
<td colspan="3" style="width: 357px; text-align: left; vertical-align: middle; height: 24px;">
<asp:Label ID="lblRoomName" runat="server" Text="Label"></asp:Label></td>
<td colspan="1" style="vertical-align: middle; width: 106px; height: 24px; text-align: left">
<strong>
Configuration</strong></td>
<td colspan="1" style="vertical-align: middle; width: 120px; height: 24px; text-align: left">
<asp:Label ID="lblRoomConfigName" runat="server" Text="Label"></asp:Label></td>
</tr>
<tr>
<td colspan="1" style="vertical-align: middle; width: 128px; height: 24px; text-align: left"
valign="top">
<strong>Max Beds</strong></td>
<td colspan="3" style="vertical-align: middle; width: 357px; height: 24px; text-align: left">
<asp:Label ID="lblBeds" runat="server" Text="Label"></asp:Label></td>
<td colspan="1" style="vertical-align: middle; width: 106px; height: 24px; text-align: left">
</td>
<td colspan="1" style="vertical-align: middle; width: 120px; height: 24px; text-align: left">
</td>
</tr>
<tr>
<td colspan="1" style="vertical-align: middle; width: 128px; height: 24px; text-align: left"
valign="top">
<strong>Room Comments</strong></td>
<td colspan="5" style="vertical-align: middle; height: 24px; text-align: left">
<asp:TextBox ID="tbComments" runat="server" Enabled="False" Height="47px" MaxLength="8"
ReadOnly="True" Style="text-align: left" TextMode="MultiLine" Width="98%"></asp:TextBox></td>
</tr>
<tr>
<td colspan="6">
<asp:Label ID="lblMsg" runat="server" Visible="False" Width="100%" BackColor="Red" Font-Bold="True" Font-Names="Arial" ForeColor="Yellow" style="text-align:center"></asp:Label>
<asp:GridView ID="gvAllocations" runat="server" AllowSorting="True" CellPadding="4"
ForeColor="#333333" GridLines="None" AutoGenerateColumns="False" Font-Names="Arial Narrow" Font-Size="10pt"
DataSourceID="sdsAllocations" DataKeyNames="BoardingCheckinID"
OnRowDataBound="gvAllocations_RowDataBound"
OnDataBound="gvAllocations_DataBound">
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<Columns>
<asp:TemplateField HeaderText="Tenant" SortExpression="TenantName">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("TenantName") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" />
</asp:TemplateField>
<asp:TemplateField HeaderText="ID" SortExpression="TenantID">
<ItemTemplate>
<asp:Label ID="Label2" runat="server" Text='<%# Eval("TenantID") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Bed" SortExpression="BedName">
<ItemTemplate>
<asp:Label ID="Label3" runat="server" Text='<%# Eval("BedName") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Center" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Checked IN" SortExpression="DateCheckedIn">
<ItemTemplate>
<asp:Label ID="lblDateCheckIn" runat="server" Text='<%# Eval("DateCheckedIn","{0:g}") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Right" />
</asp:TemplateField>
<asp:TemplateField Visible="false" ShowHeader="false">
<ItemTemplate>
<asp:Label ID="lblCheckedInBy" runat="server" Text='<%# Eval("CheckedInBy") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Expected Check Out" SortExpression="ExpectedCheckOut">
<ItemTemplate>
<asp:Label ID="Label6" runat="server" Text='<%# Eval("ExpectedCheckOut","{0:g}") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Right" />
</asp:TemplateField>
<asp:TemplateField HeaderText="Notes" SortExpression="Notes">
<ItemTemplate>
<asp:Label ID="Label7" runat="server" Text='<%# Eval("Notes") %>'></asp:Label>
</ItemTemplate>
<ItemStyle HorizontalAlign="Left" />
</asp:TemplateField>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lnkDEL" runat="server" CausesValidation="False" CommandName="Delete" Text="DEL" OnClientClick="return confirm('Are you sure?');"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="True" ForeColor="#333333" />
<HeaderStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#999999" />
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
</asp:GridView>
<asp:SqlDataSource ID="sdsAllocations" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>" CancelSelectOnNullParameter="False"
SelectCommand="SELECT bc.BoardingCheckinID, bc.BoardingRoomID, ISNULL(bc.TenantID, bc.StudentID) AS TenantID, v1.StudentPreferredName + ' ' + v1.StudentFamilyName AS TenantName, bc.BedID, bb.BedName, bc.BoardingTypeID, brt.TypeName, bc.DateCheckedIn, bc.CheckedINby, bc.ExpectedCheckOut, bc.Notes FROM tblBoardingCheckins AS bc INNER JOIN vwBoardingTenants AS v1 ON v1.StudentID = bc.StudentID AND v1.Year = YEAR(GETDATE()) INNER JOIN tblBoardingBeds AS bb ON bb.BedID
= bc.BedID INNER JOIN tblBoardingRooms AS br ON br.BoardingRoomID = bc.BoardingRoomID INNER JOIN tblBoardingRoomTypes AS brt ON brt.BoardingTypeID = bc.BoardingTypeID WHERE (bc.IsActive = 1) AND (bc.DateCheckedIn <= GETDATE()) AND (bc.ExpectedCheckOut >= GETDATE()) AND (bc.BoardingRoomID = @RoomID) ORDER BY bc.DateCheckedIn DESC"
DeleteCommand="UPDATE tblBoardingCheckins SET IsActive = 0 WHERE BoardingCheckinID = @BoardingCheckinID">
<SelectParameters>
<asp:ControlParameter ControlID="lblSelectedRoomID" Name="RoomID" />
</SelectParameters>
<DeleteParameters>
<asp:Parameter Name="BoardingCheckinID" />
</DeleteParameters>
</asp:SqlDataSource>
</td>
</tr>
<tr>
<td colspan="6">
<asp:DetailsView ID="dvRoomCheckIn" runat="server" AutoGenerateRows="False" DefaultMode="Insert" CellPadding="3"
Width="100%" BackColor="White" BorderColor="#CCCCCC" BorderStyle="None" BorderWidth="1px" OnDataBound="dvRoomCheckIn_DataBound">
<FooterStyle BackColor="White" ForeColor="#000066" />
<PagerStyle BackColor="White" ForeColor="#000066" HorizontalAlign="Left" />
<Fields>
<asp:BoundField DataField="BoardingBookingID" ReadOnly="True" Visible="False" />
<asp:TemplateField HeaderText="Pick Student">
<ItemTemplate>
<asp:DropDownList ID="ddlTenant" runat="server" DataSourceID="sdsTenants" DataTextField="StudentName" DataValueField="StudentID" AppendDataBoundItems="true">
<asp:ListItem Selected="True" Text="Please select.." Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="sdsTenants" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
SelectCommand="WITH cte AS (SELECT CASE WHEN bc.StudentID IS NULL THEN v1.StudentID ELSE NULL END AS StudentID, CASE WHEN bc.StudentID IS NULL THEN (v1.StudentPreferredName + ' ' + v1.StudentFamilyName) ELSE NULL END AS StudentName FROM vwBoardingTenants AS v1 LEFT OUTER JOIN tblBoardingCheckins AS bc ON v1.StudentID = bc.StudentID AND bc.DateCheckedIn <= GETDATE() AND bc.ExpectedCheckOut >= GETDATE() AND bc.IsActive = 1 WHERE (v1.Boarding = 'Y') AND (v1.Year = YEAR(GETDATE()))) SELECT StudentID, StudentName FROM cte AS cte_1 WHERE (StudentID IS NOT NULL) ORDER BY StudentName">
</asp:SqlDataSource>
<asp:RequiredFieldValidator ID="rfvTenant" runat="server" ControlToValidate="ddlTenant" ErrorMessage="Required" InitialValue="0" ValidationGroup="vg1"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Choose Bed">
<ItemTemplate>
<asp:DropDownList ID="ddlBeds" runat="server" DataSourceID="sdsBeds" DataTextField="BedName" DataValueField="BedID" OnDataBound="ddlBeds_DataBound">
<asp:ListItem Selected="True" Text="Select.." Value=""></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="sdsBeds" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
SelectCommand="SELECT BedID, BedName FROM tblBoardingBeds WHERE BedID <= @BedMax ORDER BY BedName">
<SelectParameters>
<asp:ControlParameter ControlID="lblBeds" Name="BedMax" Type="Int16" />
</SelectParameters>
</asp:SqlDataSource>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Check IN">
<ItemTemplate>
<table width="100%">
<tr>
<td>
<asp:Label ID="lblCheckedIN" runat="server" Text='<%# Eval("DateCheckedIn","{0:g}") %>' Width="70%"></asp:Label>
</td>
<td>
<strong style="text-align: center">BY</strong>
</td>
<td>
<asp:Label ID="lblCheckedINby" runat="server" Text='<%# Eval("CheckedINby") %>' Enabled="false"></asp:Label>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Check OUT by">
<ItemTemplate>
<table width="100%">
<tr>
<td>
<asp:TextBox ID="txtCheckOUT" runat="server" Text='<%# Bind("ExpectedCheckOut") %>' Width="80"></asp:TextBox>
<asp:ImageButton runat="Server" ID="calImg" ImageUrl="~/images/Calendar_scheduleHS.png" AlternateText="Click to show calendar" CausesValidation="False" />
<ajaxToolkit:CalendarExtender PopupButtonID="calImg" Enabled="true" TargetControlID="txtCheckOUT" ID="ce1" runat="server" Format="d/MM/yyyy" PopupPosition="TopRight"></ajaxToolkit:CalendarExtender>
<asp:RequiredFieldValidator SetFocusOnError="true" ValidationGroup="vg1" ID="RequiredFieldValidator1" runat="server" ControlToValidate="txtCheckOUT" ErrorMessage="Date is required">*</asp:RequiredFieldValidator>
<asp:CompareValidator ID="CompareValidator1" runat="server" ControlToValidate="txtCheckOUT" Operator="DataTypeCheck" Type="Date" Display="Dynamic" ErrorMessage="Invalid Date (d/M/yyyy)" SetFocusOnError="True"></asp:CompareValidator>
<asp:CompareValidator ID="CompareValidator2" runat="server" ControlToValidate="txtCheckOUT" Operator="GreaterThan" Type="Date" Display="Dynamic" ValueToCompare='<%# DateTime.Today.ToShortDateString() %>' ErrorMessage="Check out date must be greater than Checked IN date!" SetFocusOnError="True"></asp:CompareValidator>
</td>
</tr>
</table>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Comments" SortExpression="Notes">
<ItemTemplate>
<asp:TextBox ID="txtNotes" runat="server" Text='<%# Bind("Notes") %>' Width="98%" Rows="5" TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
</Fields>
<HeaderStyle BackColor="#006699" Font-Bold="True" ForeColor="White" />
<EditRowStyle BackColor="#669999" Font-Bold="True" ForeColor="White" />
<RowStyle ForeColor="#000066" />
</asp:DetailsView>
</td>
</tr>
<tr>
<td colspan="6" style="text-align: center">
<asp:Button ID="ButtonSubmit" runat="server" Text="Submit" OnClick="Submit_Click" CausesValidation="true" ValidationGroup="vg1" />
<%--
<input id="ButtonSubmit" runat="server" value="Submit" type="button" validationgroup="vg1" onserverclick="Submit_Click" causesvalidation="true" />
<input id="ButtonSubmit" runat="server" type="button" value="Submit" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions('ButtonSubmit', '', true, 'vg1', '', false, false))"/>
--%>
<asp:Button ID="ButtonCancel" runat="server" Text="Cancel" OnClick="Cancel_Click" CausesValidation="false"/>
</td>
</tr>
</table>
</asp:Panel>
</ContentTemplate> </asp:UpdatePanel>
Кнопка Отправить запускает этот код...
protected void Submit_Click(object sender, EventArgs e)
{
//find button used to get here
Button btnRoomClicked = (Button)pnlRoomDetails.FindControl("Room" + lblSelectedRoomID.Text);
if (btnRoomClicked != null)
{
//reset colours
btnRoomClicked.Font.Bold = false;
}
//Check In!
using (SqlConnection cnn = new SqlConnection(ConfigurationManager.ConnectionStrings["ATCNTV1ConnectionString"].ConnectionString))
{
cnn.Open();
try
{
//prepare command
using (SqlCommand cmd = new SqlCommand("spBoardingCheckIN", cnn))
{
cmd.CommandType = CommandType.StoredProcedure;
DropDownList ddlTenant = (DropDownList)dvRoomCheckIn.FindControl("ddlTenant");
if (ddlTenant != null) cmd.Parameters.Add("@StudentID", SqlDbType.Char).Value = ddlTenant.SelectedValue.ToString();
cmd.Parameters.Add("@TenantID", SqlDbType.VarChar).Value = string.Empty;
DropDownList ddlBed = (DropDownList)dvRoomCheckIn.FindControl("ddlBeds");
if (ddlBed != null) cmd.Parameters.Add("@BedID", SqlDbType.Int).Value = ddlBed.SelectedValue.ToString();
cmd.Parameters.Add("@BoardingRoomID", SqlDbType.Int).Value = lblSelectedRoomID.Text;
cmd.Parameters.Add("@BoardingTypeID", SqlDbType.Int).Value = 2; //Boarder types only at this stage
cmd.Parameters.Add("@StaffID", SqlDbType.VarChar).Value = (Session["StaffID"] != string.Empty) ? Session["StaffID"].ToString() : "0000000001"; //default to Admin if null
TextBox txtCheckOUT = (TextBox)dvRoomCheckIn.FindControl("txtCheckOUT");
if (txtCheckOUT != null) cmd.Parameters.Add("@ExpectedCheckOut", SqlDbType.DateTime).Value = DateTime.Parse(txtCheckOUT.Text);
TextBox txtNotes = (TextBox)dvRoomCheckIn.FindControl("txtNotes");
if (txtNotes != null) cmd.Parameters.Add("@Notes", SqlDbType.VarChar).Value = txtNotes.Text;
//run query
int tst = cmd.ExecuteNonQuery();
if (tst != 1) throw new Exception("The Insert command did not work! tst=" + tst.ToString() + " ");
}
}
catch (Exception ex)
{
lblMsg.Text = ex.Message + " - " + ex.StackTrace;
}
//re-enable main panel and hide details panel
pnlRoomDetails.Visible = false;
pnlMAIN.Enabled = true;
gvCurrCheckIns.DataBind();
//update the motel layout
MotelFormat();
}
}
Проблема в том, что когда я когда-либо отправляю нового арендатора в GridView gvAllocations
Иногда сервер выполняет PostBack, иногда он ничего не делает, и страница обновляется без новой записи, отображаемой в Gridview. Однако в последнем случае страница обновляется должным образом примерно через 15-20 секунд, и я вижу нового арендатора, добавленного в GridView. В других случаях это происходит мгновенно.
Я тестировал SQL-сервер параллельно с этим, и INSERT работает, и я сразу вижу новую строку, но по какой-то причине страница ASP.net не регистрирует это, но только через 15-20 секунд., И, как я уже сказал, это случается иногда, что еще более расстраивает.
Странно, когда я удаляю арендатора из gvAllocations
GridView, все работает отлично.
Я не уверен, что это проблема UpdatePanel здесь, или что это, возможно, плохой дизайн с моей стороны, и я должен был использовать FormView
для всего этого. Можете ли вы иметь FormViews внутри UpdatePanels? Нужно ли мне даже UpdatePanel?
Я прочитал это и положил ScriptManager RegisterPostBackControl()
ничего не изменило для меня.
Кстати, кнопка SUBMIT отображается следующим образом:
<input type="submit" name="ctl00$ContentPlaceHolder1$ButtonSubmit" value="Submit" onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$ContentPlaceHolder1$ButtonSubmit", "", true, "vg1", "", false, false))" id="ctl00_ContentPlaceHolder1_ButtonSubmit">
Кнопка ОТМЕНА не имеет WebForm_DoPostBackWithOptions()
, Зачем?
Спасибо за ваше время.
1 ответ
Ну, похоже, никто не мог помочь мне здесь, и я собирался разместить Баунти, но я нашел виновника!
Да - вы уже догадались - параметр нюхает! Мне понадобилось 4 дня, чтобы понять это.
DvRoomCheckIn DetailsView
у меня было три параметра, предварительно спроектированных в элемент управления, как вы можете видеть в приведенном выше коде - параметры были DateCheckedIn, CheckedINby и ExpectedCheckOut.
Хранимая процедура была такой...
CREATE PROCEDURE [dbo].[spBoardingCheckIN]
@StudentID CHAR(10),
@TenantID VARCHAR(20) = NULL,
@BedID INT,
@BoardingRoomID INT,
@BoardingTypeID INT,
@StaffID VARCHAR(10),
@ExpectedCheckOut DATETIME,
@Notes VARCHAR(5000)
AS
BEGIN
INSERT INTO tblBoardingCheckins(StudentID,
TenantID,
BedID,
BoardingRoomID,
BoardingTypeID,
DateCheckedIn,
CheckedINby,
ExpectedCheckOut,
Notes,
IsActive)
VALUES (@StudentID,
@TenantID,
@BedID,
@BoardingRoomID,
@BoardingTypeID,
GETDATE(),
@StaffID,
CONVERT(DATETIME, @ExpectedCheckOut, 121),
@Notes,
1)
END
GO
Итак, что произошло, так как я не указал эти три параметра в хранимой процедуре (я установил значения по умолчанию и упомянул только один из них), ASP.net (или сервер SQL?) Пошел искать значения для других два параметра, которые я упомянул в DetailsView.
Я исправил это, указав все параметры, которые ожидал ASP.net, и поэтому я изменил хранимую процедуру и список параметров в ASP.net, чтобы отразить точное число ожидаемых параметров, чтобы программа не входила в программу ". режим "сниффинг" для этих значений.
т.е.
CREATE PROCEDURE [dbo].[spBoardingCheckIN]
@StudentID CHAR(10),
@TenantID VARCHAR(20) = NULL,
@BedID INT,
@BoardingRoomID INT,
@BoardingTypeID INT,
@DateCheckedIn DATETIME,
@CheckedINby VARCHAR(10),
@ExpectedCheckOut DATETIME,
@Notes VARCHAR(5000)
AS
BEGIN
INSERT INTO tblBoardingCheckins(StudentID,
TenantID,
BedID,
BoardingRoomID,
BoardingTypeID,
DateCheckedIn,
CheckedINby,
ExpectedCheckOut,
Notes,
IsActive)
VALUES (@StudentID,
@TenantID,
@BedID,
@BoardingRoomID,
@BoardingTypeID,
@DateCheckedIn,
@CheckedINby,
CONVERT(DATETIME, @ExpectedCheckOut, 121),
@Notes,
1)
END
GO
И SqlDataSource в ASP.net таким образом...
<asp:SqlDataSource ID="sdsCheckinEntries" runat="server" ConnectionString="<%$ ConnectionStrings:ATCNTV1ConnectionString %>"
InsertCommand="spBoardingCheckIN" InsertCommandType="StoredProcedure" EnableCaching="false">
<InsertParameters>
<asp:ControlParameter ControlID="dvRoomCheckIn$ddlTenant" Name="StudentID" Type="string" />
<asp:Parameter Name="TenantID" Type="string" DefaultValue="" ConvertEmptyStringToNull="true" />
<asp:ControlParameter ControlID="dvRoomCheckIn$ddlBeds" Name="BedID" Type="int16" />
<asp:ControlParameter ControlID="lblSelectedRoomID" Name="BoardingRoomID" Type="Int16" />
<asp:Parameter Name="BoardingTypeID" Type="int16" DefaultValue="2" />
<asp:ControlParameter ControlID="dvRoomCheckIn$lblCheckedIN" Name="DateCheckedIn" Type="DateTime" />
<asp:ControlParameter ControlID="dvRoomCheckIn$lblCheckedINby" Name="CheckedINby" Type="string" />
<asp:ControlParameter ControlID="dvRoomCheckIn$txtCheckOUT" Name="ExpectedCheckOut" Type="DateTime" />
<asp:ControlParameter ControlID="dvRoomCheckIn$txtNotes" Name="Notes" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
Так что да извлекли уроки! Не думайте, что только потому, что в элементе управления есть параметр, он автоматически и напрямую связан с источником данных. Иногда программа может не "найти его" и вынуждена искать значения, связанные с отсутствующими параметрами.
Отличный ресурс - если не лучший, который я нашел до сих пор, так это. Это все объясняет.
Я надеюсь, что это поможет кому-то еще вырвать их волосы!
ура