Различие между RegisterStartupScript и RegisterClientScriptBlock?

Ответ на этот вопрос оказывается очень простым, но его также сложно определить, если вы ищете неправильное место.

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

musicPlayerController.beginGeneratingPlaybackNotifications()

NotificationCenter.default.addObserver(self,
                                       selector: #selector(refreshView),
                                       name: .MPMusicPlayerControllerPlaybackStateDidChange,
                                       object: musicPlayerController)

NotificationCenter.default.addObserver(self,
                                       selector: #selector(refreshView),
                                       name: .MPMusicPlayerControllerNowPlayingItemDidChange,
                                       object: musicPlayerController)

Нам также нужно помнить, чтобы завершить генерацию их, когда мы оставляем (освобождаем) вид:

deinit {
    NotificationCenter.default.removeObserver(self, name: .MPMusicPlayerControllerPlaybackStateDidChange, object: nil)
    NotificationCenter.default.removeObserver(self, name: .MPMusicPlayerControllerNowPlayingItemDidChange, object: nil)
    musicPlayerController.endGeneratingPlaybackNotifications()
}

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

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

136
задан KyleMit 27 May 2014 в 19:15
поделиться

1 ответ

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

Для объяснения различий как относящиеся к отправленному примеру:

a. Когда Вы будете использовать RegisterStartupScript, это представит Ваш сценарий после все элементы на странице (прямо перед конечным тэгом формы). Это позволяет сценарию звонить или элементы ссылочной страницы без возможности его не нахождение их в DOM Страницы.

Вот представленный источник страницы, когда Вы вызываете RegisterStartupScript метод:

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1"><title></title></head>
<body>
    <form name="form1" method="post" action="StartupScript.aspx" id="form1">
        <div>
            <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish" />
        </div>
        <div> <span id="lblDisplayDate">Label</span>
            <br />
            <input type="submit" name="btnPostback" value="Register Startup Script" id="btnPostback" />
            <br />
            <input type="submit" name="btnPostBack2" value="Register" id="btnPostBack2" />
        </div>
        <div>
            <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="someViewstategibberish" />
        </div>
        <!-- Note this part -->
        <script language='javascript'>
            var lbl = document.getElementById('lblDisplayDate');
            lbl.style.color = 'red';
        </script>
    </form>
    <!-- Note this part -->
</body>
</html>

b. Когда Вы используете RegisterClientScriptBlock, сценарий представляется прямо после тега Состояния отображения, но перед любым из элементов страницы. Так как это - прямой сценарий (не функция, которая может быть названа , это будет сразу выполнено браузером. Но браузер не находит маркировку в DOM Страницы на данном этапе, и следовательно необходимо получить "Объект, не найденный" ошибка.

Вот представленный источник страницы, когда Вы вызываете RegisterClientScriptBlock метод:

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1"><title></title></head>
<body>
    <form name="form1" method="post" action="StartupScript.aspx" id="form1">
        <div>
            <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="someViewstategibberish" />
        </div>
        <script language='javascript'>
            var lbl = document.getElementById('lblDisplayDate');
            // Error is thrown in the next line because lbl is null.
            lbl.style.color = 'green';

Поэтому для суммирования необходимо назвать последний метод, если Вы намереваетесь представить функциональное определение. Можно тогда представить эти вызов к той функции использование бывшего метода (или добавить клиентский атрибут).

Редактирование после комментариев:

<час>

, Например, следующая функция работала бы:

protected void btnPostBack2_Click(object sender, EventArgs e) 
{ 
  System.Text.StringBuilder sb = new System.Text.StringBuilder(); 
  sb.Append("<script language='javascript'>function ChangeColor() {"); 
  sb.Append("var lbl = document.getElementById('lblDisplayDate');"); 
  sb.Append("lbl.style.color='green';"); 
  sb.Append("}</script>"); 

  //Render the function definition. 
  if (!ClientScript.IsClientScriptBlockRegistered("JSScriptBlock")) 
  {
    ClientScript.RegisterClientScriptBlock(this.GetType(), "JSScriptBlock", sb.ToString()); 
  }

  //Render the function invocation. 
  string funcCall = "<script language='javascript'>ChangeColor();</script>"; 

  if (!ClientScript.IsStartupScriptRegistered("JSScript"))
  { 
    ClientScript.RegisterStartupScript(this.GetType(), "JSScript", funcCall); 
  } 
} 
157
ответ дан 23 November 2019 в 23:41
поделиться