【问题标题】:ASP.NET - How can I add a new javascript from a user control loaded by callback?ASP.NET - 如何从回调加载的用户控件中添加新的 javascript?
【发布时间】:2010-09-10 08:55:00
【问题描述】:

我正在做一个动态加载关卡的菜单,当你点击一个项目时,下一个关卡会异步加载。对于每个菜单项,我都有一个用户控件。每个用户控件都在其父级中声明,例如,“secondlevelcontrol”引用了“thirdlevelcontrol”。

使用这一级别的嵌套,我想管理每个用户控件上的异步调用,因此,当加载第一级时,加载第二级的 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 接口?或者,我做错了什么,这不是实现这种行为的正确方法吗?

谢谢!!!

【问题讨论】:

  • 希望您不要介意,我编辑了标签以更好地反映问题。我添加了 Javascript,因为这个标签似乎被很多人关注,你应该得到更多的答案
  • 我认为“jquery”不是正确的标签,也不是“javascript”,因为问题不在于那个。我认为问题在于我使用 ASP.Net 的方式以及如何创建异步方法。

标签: asp.net user-controls callback


【解决方案1】:

我怀疑您可能以错误的方式处理此问题。看看这个问题的答案:How to lazy load Infragistics UltraWebTree control?

这个问题专门针对延迟加载树视图,但同样的原则也适用于延迟加载菜单项。请按以下步骤操作:

  1. 在第一页加载时,呈现顶级菜单
  2. 在页面上包含一个函数,该函数使用 父 id 并为该父返回下一级项目(在我的示例中为 getNodes)
  3. 将此函数绑定到顶级菜单项(具有子项)的点击事件
  4. 在ajax调用的成功处理程序中,注入下面返回的菜单项 父项并将相同的功能绑定到这些项目的单击事件。

在回调时,注意不要将函数绑定到所有菜单项的点击事件,因为那样你最终会得到函数多次绑定到顶层项目并被多次调用。只需绑定到返回的项目。

此外,您需要某种方法来确定项目的子项目是否已加载。这就是我示例中以下行的用途,但您可能需要稍有不同的内容:

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

我使用 jQuery 是因为它最简洁,但你可以在纯 js 中执行此操作 - 我不推荐它。

【讨论】:

  • 很好的答案,但我无法创建 Web 服务。我想使用 ICallbackEventHandler 来执行此操作,尽管我认为我的方法有问题。
  • 你可以在你的页面上使用 webmethod。您无需创建单独的网络服务。
猜你喜欢
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-24
  • 2014-08-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多