这是我正在处理的webapp中遇到的一个问题
因此,我没有使用不相关的代码来混淆问题,而是在一个孤立的,简化的webapp中重新创建了问题,只展示了这个问题。
希望这有助于找到解决方案。
我有一个网络用户控件,其内容为:
<% if (ShowAlertScript)
{ %>
<script type="text/javascript">
function AlertMe()
{
alert('Hello World!');
}
</script>
<% } %>
<input type="button" onclick="AlertMe()" value="Say Hello" />
它的代码隐藏只不过是ShowAlertScript
的布尔定义
这表示我在大型webapp中具有的控件有两种模式:输入模式和显示模式。在输入模式时,它有一个大的javascript块,只有在那时才有用;它做了一些很酷的东西来帮助用户输入信息。
这种控制在大局中的布局如下:
<asp:ScriptManager runat="server" />
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:MultiView ActiveViewIndex="0" runat="server" ID="mvw">
<asp:View runat="server">
<asp:Button runat="server" ID="btnSwitch"
OnClick="btnSwitch_Click" Text="Switch" />
</asp:View>
<asp:View runat="server">
<uc:MyInputControl runat="server" ID="micInput" ShowAlertScript="true" />
</asp:View>
</asp:MultiView>
</ContentTemplate>
</asp:UpdatePanel>
单击btnSwitch
时,只需使用用户控件切换到第二个视图。
请注意我已将ShowAlertScript
初始化为true
的方式
可能的输出是,因为我在用户控件中“显示警报脚本”,所以{»1}}函数将在您单击AlertMe()
元素时执行,因为它是根据内联{{ 1}}陈述。
如果你运行这段代码,我到目前为止,它将无法正常工作
浏览器会说它看不到input-button
功能;据它所知,它是未定义的。
但是,如果您取出if
(或禁用AlertMe()
的部分呈现),当您点击UpdatePanel
时,它将在完整回发时正常工作。
我希望它能用于部分回发,因为与页面的其他部分相比,这一切都是一小部分,我不希望每次切换视图时都进行完整的回发。
显然,ScriptManager
甚至无法重新渲染ascx文件以进行可能的更改
要么btnSwitch
不够智能,要么我缺少一个让它呈现ScriptManager
的选项,所以我可以在客户端调用它的方法。
有人可能会建议的一个潜在答案是“你为什么不拿出javascript,把它放在自己的.js文件中,并让页面引用它以便控件可以使用它?”
这对我来说无法真正起作用,因为脚本块会对该单个控件实例进行一些初始化和修改,而不是对页面上的所有其他实例进行初始化和修改。
反过来,您可能还会担心如果我有多个控件实例,我最终会得到相同脚本的副本。并不是的;在任何给定的时间内,页面中只有一个输入模式,这只是我在两个单独的视图中有这两种模式,我让用户在它们之间切换。
感谢您阅读这篇文章=) 感谢任何帮助和意见。
答案 0 :(得分:7)
要让您的脚本块正确支持partial page rendering,您必须使用ScriptManager.RegisterClientScriptBlock()方法在用户控件的PreRender
阶段进行注册:
protected void Page_PreRender(object sender, EventArgs e)
{
if (ShowAlertScript) {
ScriptManager.RegisterClientScriptBlock(this,
typeof(YourUserControl), "AlertScript",
@"function AlertMe()
{
alert('Hello World!');
}",
true);
}
}
(以上假设您在AutoEventWireup
文件的@ Control指令中将true
属性设置为ascx
。
此外,由于脚本是从用户控件注册的,但您的ScriptManager驻留在页面本身上,因此您可能需要在控件标记中添加<asp:ScriptManagerProxy>
元素才能使上述工作正常工作
答案 1 :(得分:1)
UpdatePanel实际上通过对应于UpdatePanel控件的div上的AJAX框架设置innerHTML
更改了其内容。
设置innerHTML时不执行脚本元素。
因此,在部分回发期间无法执行内联(即声明性)JS。