Как проверить, зарегистрирован ли клиент script во время частичной обратной передачи
Ниже приведен код, который я использовал в настоящее время.
if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey))
{
ScriptManager scriptManager = ScriptManager.GetCurrent(page);
if (scriptManager != null && scriptManager.IsInAsyncPostBack)
{
//if a MS AJAX request, use the Scriptmanager class
ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true);
}
else
{
//if a standard postback, use the standard ClientScript method
Page.ClientScript.RegisterStartupScript(Page.GetType(), scriptKey, script, true);
}
}
Я делаю так, как было предложено в этом ответе, чтобы я мог зарегистрировать стартап script в оба раза, т.е. когда есть частичная обратная передача и полная обратная передача.
Проблема всегда Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey)
(даже если зарегистрирован script) возвращает false, когда это частичная обратная передача. И я не смог найти ScriptManager.IsStartupScriptRegistered(статический) метод. В результате этого на всех частичных/асинхронных обратных передачах выделяется дополнительный script.
Обратите внимание, что я использую script менеджер AjaxControlToolkit версии 4.1 i.e. ToolkitScriptManager
на моей главной странице. Но я не думаю, что это имеет какое-то отношение к этому.
UPDATE
<asp:UpdatePanel ID="ContactDetailsUpdatePanel" UpdateMode="Conditional" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="UpdateContactDetailsButton" EventName="Click" />
</Triggers>
<ContentTemplate>
<div id="ContactDetailsContent" class="contact_details_content">
<div class="customer_contactdetails_left_pane">
<div class="customer_name_field">
<asp:Label ID="CustomerNameLabel" runat="server" Text="Customer" />
<asp:TextBox ID="CustomerNameValue" runat="server" />
</div>
<div class="customer_address_field">
<asp:Label ID="CustomerAddressLabel" runat="server" Text="Address" />
<asp:TextBox ID="CustomerAddressValue" runat="server" />
<asp:TextBox ID="CustomerAddressValue1" runat="server" />
<asp:TextBox ID="CustomerAddressValue2" runat="server" />
<asp:TextBox ID="CustomerAddressValue3" runat="server" />
</div>
<div class="customer_postcode_field">
<asp:Label ID="CustomerPostcodeLabel" runat="server" Text="Postcode" />
<asp:TextBox ID="CustomerPostcodeValue" runat="server" />
</div>
</div>
<div class="customer_contactdetails_right_pane">
<div>
<asp:Label ID="CustomerContactLabel" runat="server" Text="Contact" />
<asp:TextBox ID="CustomerContactValue" runat="server" />
</div>
<div>
<asp:Label ID="CustomerTelephoneLabel" runat="server" Text="Telephone" />
<asp:TextBox ID="CustomerTelephoneValue" runat="server" />
</div>
<div>
<asp:Label ID="CustomerMobileLabel" runat="server" Text="Mobile" />
<asp:TextBox ID="CustomerMobileValue" runat="server" />
</div>
<div>
<asp:Label ID="CustomerFaxLabel" runat="server" Text="Fax" />
<asp:TextBox ID="CustomerFaxValue" runat="server" />
</div>
<div>
<asp:Label ID="CustomerEmailLabel" runat="server" Text="Email" />
<asp:TextBox ID="CustomerEmailValue" runat="server" />
</div>
<div>
<asp:Label ID="CustomerWebLabel" runat="server" Text="Web" />
<asp:TextBox ID="CustomerWebValue" runat="server" />
</div>
</div>
</div>
<div class="update_button_field">
<asp:Button ID="UpdateContactDetailsButton" runat="server" Text="Update"
onclick="UpdateContactDetailsButton_Click" />
</div>
</ContentTemplate>
</asp:UpdatePanel>
Спасибо заранее.
ПРИМЕЧАНИЕ.. Чтобы понять ход выполнения этой проблемы, см. комментарии к этому перед ответом.
UPDATE
Я применил временное решение этой проблемы, поставив чек в javascript, который, если script уже выполняется, не выполняет дважды. Javascript по-прежнему много раз перетаскивается на каждую частичную обратную передачу. Не удалось это предотвратить.
По мере увеличения взглядов на эту должность я вижу, что есть другие люди, которые могут также хотеть ответить на эту проблему.
Ответы
Ответ 1
Если вы используете это,
Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "noPasswordMatch", script, true);
Затем, чтобы проверить, была ли она зарегистрирована, вы должны использовать это:
if (Page.ClientScript.IsClientScriptBlockRegistered(this.GetType(), "noPasswordMatch"))
if (Page.ClientScript.IsClientScriptBlockRegistered("noPasswordMatch"))
не работает!
Ответ 2
Я столкнулся с этой проблемой при написании составного элемента управления в ASP.Net. Когда элемент управления находился внутри панели обновления, страница .ClientScript.IsStartupScriptRegistered не работала. Изнутри метода protected override void CreateChildControls() я делал что-то вроде
ScriptManager.RegisterStartupScript(this.Page, this.Page.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true);
Следовательно, я столкнулся с ситуацией, подобной тому, что вы здесь описываете. То, что решило мою проблему, заключалось в передаче элемента управления и его типа вместо типа страницы и страницы ScriptManager.RegisterStartupScript. Следовательно, теперь код выглядит,
ScriptManager.RegisterStartupScript(this, this.GetType(), initializeTokenInputScriptKey, initializeTokenInputScript, true);
Как только я сделал это изменение, мне больше не нужно было проверять страницу .ClientScript.IsStartupScriptRegistered. Теперь мой контроль работает с панелями обновлений или без них. Также нет лишних js spitouts. Надеюсь, что это поможет
Ответ 3
Я применил временное решение этой проблемы, поставив чек в javascript, который, если script уже выполняется, не выполняет дважды. Javascript по-прежнему много раз перетаскивается на каждую частичную обратную передачу. Не удалось это предотвратить.
Ответ 4
Я написал метод расширения, чтобы проверить, был ли script уже зарегистрирован в ScriptManager. Вы можете использовать тот же принцип для проверки сценариев запуска:
public static bool IsClientScriptBlockRegistered(this ScriptManager sm, string key)
{
ReadOnlyCollection<RegisteredScript> scriptBlocks = sm.GetRegisteredClientScriptBlocks();
foreach (RegisteredScript rs in scriptBlocks)
{
if (rs.Key == key)
return true;
}
return false;
}
Ответ 5
Помните, что ваша первая строка кода является обратной величиной возвращаемого метода из-за !
.
if (!Page.ClientScript.IsStartupScriptRegistered(Page.GetType(), scriptKey))
Если IsStartupScriptRegistered
возвращает false
, как вы говорите, тогда оператор if должен оценивать true
из-за !
. Это должно привести к тому, что script будет зарегистрирован как ожидалось.
Ваш код основан на моем ответе здесь, который был основан на ASP.NET AJAX 1.0 и ASP.NET 2.0. Это может иметь какое-то отношение к .NET 3.5, хотя я считаю, что уже использовал выше в новом проекте, который мы делали под 3.5, и он отлично работал...
Можете ли вы опубликовать некоторую разметку, чтобы перейти с кодом?
EDIT: Спасибо за публикацию разметки.
Теперь я замечаю 2 вещи:
Вы упомянули, что используете ToolkitScriptManager
. Это элемент управления, который наследуется от ScriptManager. Я этого раньше не заметил, но ваш код по-прежнему напрямую ссылается на ScriptManager. Вы сказали, что во время асинхронных обратных передач, что script не работает, что заставляет меня думать, что это проблема с вашей ссылкой на ScriptManager. Я никогда не использовал ToolkitScriptManager, поэтому я не могу дать вам точный код, но могу сказать, что вам, скорее всего, потребуется обновить код, изменив все ссылки на ScriptManager и его методы/свойства на эквивалент в ToolkitScriptManager.
Попробуйте добавить точку останова в инструкции if и убедитесь, что она равна true. Я не удивлюсь, если scriptManager
null
, или scriptManager.IsInAsyncPostBack
есть false
, потому что вы используете ToolkitScriptManager
.
ScriptManager scriptManager = ScriptManager.GetCurrent(page);
if (scriptManager != null && scriptManager.IsInAsyncPostBack)
{
//if a MS AJAX request, use the Scriptmanager class
ScriptManager.RegisterStartupScript(Page, Page.GetType(), scriptKey, script, true);
}
Наконец - Ваша разметка выглядит нормально, кроме раздела <Triggers>
. Триггеры позволяют вам указать элемент управления, который находится за пределами вашей панели обновления, чтобы вызвать частичную визуализацию. Любое дочернее управление панелью обновления в разделе <ContentTemplate>
сделает это автоматически. Кнопка, которую вы настраиваете в разделе "Триггеры", уже находится в панели обновления. Хотя я не думаю, что это причина вашей проблемы, я все равно удалю ее.
Надеюсь, что это поможет.
Ответ 6
Вы имели в виду это: ClientScriptManager.IsStartupScriptRegistered Method