ASP.NET - Как я могу добавить новый JavaScript из пользовательского элемента управления, загруженного с помощью обратного вызова? - PullRequest
1 голос
/ 10 сентября 2010

Я делаю меню, которое загружает уровни динамически, когда вы нажимаете на элемент, следующий уровень загружается асинхронно. Для каждого пункта меню у меня есть пользовательский элемент управления. Каждый пользовательский элемент управления объявляется в его родительском элементе, например, «secondlevelcontrol» имеет ссылку на «третий уровень управления».

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

Для выполнения асинхронных вызовов я реализую интерфейс ICallbackEventHandler. Как видно из примеров, элементы управления добавляются на страницу в виде обычного HTML. Метод ProcessOnLoadEvent выполняет все строки события «OnLoad» пользовательского элемента управления.

Примером реализации является пользовательский элемент управления четвертого уровня:

public string GetCallbackResult()
{
    return _callbackRendering;
}

public void RaiseCallbackEvent(string itemId)
{
    var id = Int32.Parse(itemId);
    var menu = new LateralMenu();
    var currentChildren = menu.GetNodesById(id, 1);

    var ctrl = this.Page.LoadControl(USER_CONTROL_FIVE_LEVEL_RELATIVE_PATH) as LeftSideFifthLevel;
    ctrl.Items = currentChildren.Children;
    ctrl.ProcessOnLoadEvent();

    _callbackRendering = ctrl.GetHtml();
}

А это код для пользовательского элемента управления пятого уровня:

public void ProcessOnLoadEvent()
{
    EnsureChildControls();

    if (null != RepeaterMenu)
    {
        SettingCallbackReference();

        Visible = null != Items && 0 < Items.Count;

        if (null != Items && 0 < Items.Count)
        {
            RepeaterMenu.DataSource = Items;
            RepeaterMenu.DataBind();
        }
    }
}

public void RaiseCallbackEvent(string itemId)
{
    var id = Int32.Parse(itemId);
    var menu = new LateralMenu();
    var currentChildren = menu.GetNodesById(id, 1);

    var ctrl = this.Page.LoadControl(USER_CONTROL_SIX_LEVEL_RELATIVE_PATH) as LeftSideSixthLevel;
    ctrl.Items = currentChildren.Children;
    ctrl.ProcessOnLoadEvent();

    _callbackRendering = ctrl.GetHtml();
}

public void SettingCallbackReference()
{
    var cm = this.Page.ClientScript;
    var cbRef = cm.GetCallbackEventReference(this, "itemId", "AnchorLevel5_OnClick_Callback", "ctx");
    var cbScript = "function AnchorLevel5_OnClick(itemId, ctx){ new Menu().empty(ctx); " + cbRef + "; }";
    cbScript += "function AnchorLevel5_OnClick_Callback(htmlText, ctx){ new Menu().render(htmlText, ctx); }";
    cm.RegisterClientScriptBlock(this.GetType(), "CallServer", cbScript, true);
}

Моя проблема в том, что уровни за пределами второго уровня никогда не работают, потому что JavaScript, связанный с пользовательским элементом управления (метод «SettingCallbackReference»), не имеет html для размещения на странице.

Есть ли способ создать некоторые пользовательские элементы управления, созданные динамически, которые реализуют интерфейс ICallbackEventHandler, который добавляет новые пользовательские элементы управления на страницу? Или я что-то не так делаю, и это неправильный способ реализовать это поведение?

Спасибо !!!

1 Ответ

0 голосов
/ 10 сентября 2010

Я подозреваю, что вы, вероятно, ошибаетесь. Взгляните на ответ на этот вопрос: Как лениво загрузить Infragistics UltraWebTree control?

Этот вопрос был специально о отложенной загрузке дерева, но те же принципы применимы к отложенной загрузке пунктов меню. Выполните следующие действия:

  1. При первой загрузке страницы отобразить меню верхнего уровня
  2. Включите функцию на странице, которая делает AJAX-вызов на сервер с родительский идентификатор и возвращает элементы следующего уровня для этого родителя (в моем примере getNodes)
  3. Свяжите эту функцию с событием щелчка пунктов меню верхнего уровня (которые имеют подпункты)
  4. В обработчике успеха вызова ajax введите возвращаемые пункты меню ниже родитель и привязать ту же функцию к событию щелчка только этих элементов.

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

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

 if (jQuery(nodesDiv).text() == 'Loading...') {

Я использовал jQuery, потому что он самый лаконичный, но вы должны делать это на чистом js - я бы не советовал.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...