ScriptManager добавление скрипта несколько раз на страницу (дубликаты) - PullRequest
3 голосов
/ 03 декабря 2010

Это точно такой же вопрос, как и этот без ответа от мая.

(правка) Примечание: этот пост, оставшийся без ответа, точно описывает поведение - дополнительные скрипты, добавляемые в <head> ScriptManager.RegisterClientScriptBlock в usercontrol, в UpdatePanel, вызывают дубликаты. C # .NET 4.0. Страница структурирована так:

MasterPage
   Page
      UserControl1 (ascx) - loaded in code by Page
         UpdatePanel
            UserControl2 (ascx) - loaded in code by UserControl1

При первом добавлении сценария в тело, как и ожидалось. Код просто в UserControl2 OnInit:

ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);

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

После частичной обратной передачи сценарий добавляется снова - но, как ни странно, в <head> страницы, а не в теле, и, что интересно, не хватает обычной оболочки //<![CDATA[...//]]>, которую обычно добавляет asp.net.

Другой скрипт, добавленный UserControl1, дублируется точно так же после частичной обратной передачи.

Кто-нибудь знает, почему это происходит?

Ответы [ 3 ]

3 голосов
/ 21 декабря 2010

Хотя я не могу найти много дискуссий об этом так или иначе, кажется, что ScriptManager не имеет состояния.Таким образом, добавление скрипта с одинаковым тегом в частичные обратные вызовы приведет к дублированию.На практике (для меня) это нежелательное поведение в большинстве случаев, поскольку можно предположить, что любой сценарий, который вы регистрируете более одного раза в UserControl с одним и тем же тегом, будет дубликатом и не должен быть перерегистрирован.Если вы действительно хотите зарегистрировать новый сценарий (например, в результате того, что произошло после частичной обратной передачи), я думаю, вы должны предоставить ему новый тег для ScriptManager, чтобы зарегистрировать его снова.

MyРешение заключается в создании пользовательского ScriptManager для использования в UserControls, в котором есть методы, которые регистрируют сценарий только при первой загрузке элемента управления и поддерживают информацию о состоянии с помощью ViewState.То есть я храню список тегов для сценариев, предназначенных для регистрации только в первый раз, и сохраняю его в постбэках, и переписываю только те сценарии, которые не найдены в этом списке.Сценарии, которые являются просто общей поддержкой usercontrol и должны быть зарегистрированы только один раз, отслеживаются таким образом.

Причина, по которой я не могу просто использовать IsPostBack, заключается в том, что я иногда загружаю usercontrols динамически, используя Page.LoadControl.Не гарантируется, что элемент управления будет загружен при первой загрузке всей страницы.То есть он может быть впервые загружен при обратной передаче.Так что, если я только что использовал IsPostBack, сценарии никогда не будут зарегистрированы.

3 голосов
/ 03 декабря 2010

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

if (!Page.ClientScript.IsClientScriptRegistered (Page.GetType(), "myscript"))
   ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);

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

2 голосов
/ 08 декабря 2010

Вы пытались обернуть свой код простым предложением IsPostBack внутри функции Init / Load / PreRender / Render страницы? Это предотвратит регистрацию скрипта после загрузки первой страницы.

if(!IsPostBack)
{
    ScriptManager.RegisterClientScriptBlock(Page, Page.GetType(), "myscript", script, true);
}
...