ASP.NET WebForms: как получить доступ к Javascript в невидимом, не отображаемом виде после того, как он стал видимым через UpdatePanel?

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

У меня есть пользовательский элемент управления. В этом usercontrol есть блок Javascript, который содержит функции, связанные с событиями onclick и onchange различных элементов управления. Раньше свойство .Visible элемента управления было True, поэтому его HTML и Javascript отображались на странице.

Теперь мне нужно установить для свойства .Visible моего элемента управления значение false и обернуть вокруг него UpdatePanel. Это предотвращает отрисовку HTML-кода элемента управления во время начальной загрузки страницы. Чтобы отобразить содержимое элемента управления, пользователь должен нажать кнопку, которая вызывает метод на стороне сервера, который устанавливает для свойства .Visible элемента управления значение true. Поскольку теперь он находится в UpdatePanel, элемент управления отображается на странице в некотором роде Ajaxy. Однако оказывается, что Javascript, расположенный в элементе управления, недоступен, поэтому ни одно из событий onclick и onchange дочерних элементов управления не работает, поскольку связанные с ними функции Javascript имеют значение undefined.

Решения, которые я предпочитаю не использовать по причинам, слишком сложным для краткости:

  • JSON/AJAX (слишком много новой архитектуры за такое короткое время)
  • CSS display:none/visibility:visible (мне нужно сохранить как можно больше серверной функциональности, чтобы свести к минимуму повторную архитектуру)
  • Поместите Javascript на родительскую страницу или в файл .js (я буду рассматривать это как крайнюю меру, но я ссылаюсь на серверные элементы управления, используя <#%=ControlId.ClientID %>. Вы не можете сделать это, если Javascript не содержится в UserControl, и я не хочу чтобы установить элементы управления с ClientIdMode на static.)

Мне бы очень хотелось найти способ сохранить Javascript в моем UserControl таким образом, чтобы он был доступен клиенту, когда UpdatePanel устанавливает для свойства .Visible элемента управления значение true с помощью UpdatePanel.


person oscilatingcretin    schedule 14.09.2012    source источник
comment
Вы когда-нибудь придумывали решение для этого? Я имею ту же самую проблему   -  person Al Belmondo    schedule 23.08.2016


Ответы (1)


Самый простой способ сделать это — включить javascript в качестве большой строки в исходный код и зарегистрировать его при загрузке:

        protected void Page_Load(object sender, EventArgs e)
        {
            string javasriptToRegister = @"
  function MyAwesomeJavaScriptFunction() {
     alert( document.getElementById('" + this.txtCatName.ClientID + @"').value );
  }";
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "MyControlsJavaScript", javasriptToRegister, true);
        }

Это ни в коем случае не самый чистый способ сделать это, но он будет работать.

Если вы хотите сделать это немного чище, вы можете включить внешний файл javascript либо с синглтоном, либо с прототипом объекта, представляющим ваш элемент управления (в зависимости от вашего варианта использования). Затем вы можете установить свойства объекта/синглтона для вашего идентификатора клиента в меньшем скрипте, включенном, как мы сделали выше. Например:

Javascript:

function MyControlScriptModel() {
  this.txtCatNameClientId = '';
  this.othercontainedValue = 0;
  this.anothercontainedValue = 0;
}

MyControlScriptModel.prototype.DoSomethingWithCatName = function () {
  alert( document.getElementById( this.txtCatNameClientId ).value );
}

Код позади:

        protected void Page_Load(object sender, EventArgs e)
        {
            string javasriptToRegister = string.Format(@"var obj = new MyControlScriptModel();
                                                         obj.txtCatNameClientId = '{0}';", this.txtCatNameClientId);
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "MyControlsJavaScript", javasriptToRegister, true);
        }
person Jaime Torres    schedule 14.09.2012