Подтвердить что ты не робот

Как проверить, зарегистрирован ли клиент 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 по-прежнему много раз перетаскивается на каждую частичную обратную передачу. Не удалось это предотвратить.

По мере увеличения взглядов на эту должность я вижу, что есть другие люди, которые могут также хотеть ответить на эту проблему.

4b9b3361

Ответ 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> сделает это автоматически. Кнопка, которую вы настраиваете в разделе "Триггеры", уже находится в панели обновления. Хотя я не думаю, что это причина вашей проблемы, я все равно удалю ее.

Надеюсь, что это поможет.