有一段时间我花了几个小时和几天来创建一个简单而流畅的方法来创建一个可以处理脚本加载的WebControl。根据服务器端参数(如用户是否登录),控件可以决定是否将脚本加载到客户端。
我们称之为CombinedScripts。
昨天我正在评论有关此主题的问题。可悲的是,当我今天早上给它写了一个答案时,它被运营商删除了。我迟到了12分钟,说错误回复。现在我尝试在这里重新提出这个问题,听听你的(观众)并在接下来的15分钟内给我答案。这当然是免费的回复和提出想法,我会接受 - 标记如果有人做得比我好,那么最合适的答案。
谷歌说了很多关于如何使这些事情发挥作用的事情。在途中似乎还有一些棘手的部分。脚本的路径,当它不起作用时的行为(因为它易于编译)。还有一个web.config设置用于在项目中注册组件。问题是尝试尽可能使控件独立,嵌入资源并将控制移动到其他项目以便重复使用。
答案 0 :(得分:1)
这有一些技术上棘手的部分,我试着在这里介绍它们。我花了一些时间在谷歌上,直到我终于得到了所有的碎片。我肯定无法帮助你。其中一些是非常本地的实际情况。事实上,我从来没有在我的场景中找到任何合适的信息,这并没有引导我使用意大利面条代码,拥抱代码库等等。
您只需在新类中覆盖System.Web.UI.Webcontrols.Webcontrol即可创建复合控件。由于您的兴趣,我使用CombinedScript作为名称。这个名字当然可以是任何东西。
public class CombinedScript : System.Web.UI.WebControls.WebControl
{
}
覆盖它时,您可以使用一些方法。下面有几种方法,但你必须谷歌根据你需要的最佳套件。
protected override void OnPreRender(EventArgs e)
{
}
protected override void Render(HtmlTextWriter writer)
{
}
重点是方法是在生成控件内容到客户端之前,之后和之后做的事情。 OnPreRender发生在之前,即。
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ClientScriptManager cs = this.Page.ClientScript;
cs.RegisterClientScriptResource(typeof(WebControls.CombinedScript), "Project.Script.Common.js");
cs.RegisterClientScriptResource(typeof(WebControls.CombinedScript), "Project.Script.JQuery.js");
cs.RegisterClientScriptResource(typeof(WebControls.CombinedScript), "Project.Script.JCharts.js");
}
这里有一个棘手的问题是脚本的路径。 “Project”是DLL程序集的基本名称。 “脚本”是区分大小写的路径,脚本文件位于该路径中(从项目基本路径计算)。最后一部分是文件的区分大小写的名称。我不确定,但我认为如果你把所有的东西都留在根本上,路径技巧就不成问题了。
WebControls.CombinedScript正如您所见,是控件的名称。要在ASP.NET页面中使用,必须在web.config中注册。
<pages>
<controls>
<add assembly="Project" tagPrefix="myname" namespace="Project.WebControls" />
</controls>
</pages>
当加载站点时,那些RegisterClientScriptResource使脚本加载为GET /WebResource.axd?d=MTVCK_diZif7wEDQp9UGv-GlqPKP-WXGPNEqr-mq_RnUKWDgSydkLxIuSusdnolRQsR-wpNbTpfJzAVtsonjuwVUqzguotspQFImk6-auSF3N18eVOXbYh_-6NHovgR90&t
。如果他们不这样做,那就有问题了。即错误的路径,忘记将js包含为嵌入式资源等等。
完成上述所有操作后,您注册DLL,添加命名空间/控制标记,然后使用<myname:CombinedScript runat="server" />
您可以执行以下操作,将公共属性添加到Composite Control中
public int ScriptType {get;set;}
。将属性放入控件<myname:CombinedScript ScriptType="1" runat="server" />
。并添加if (this.ScriptType == 1) { ..evaluate what script to load.. }
。当然,可以从客户端更改此类评估(任何人都可以将其生成的html替换为另一个ScriptType ID)。
我认为你可以更好地调查自己。您需要用于评估要加载的脚本的语句。上面的最后一个示例是一种方式,您当然可以在RegisterClientScriptResources之间放置任何类型的逻辑。
我被谈到了RenderControl和Render
您可以像这样使用它,
protected override void Render(HtmlTextWriter writer)
{
HttpResponseSubstitutionCallback callback = new HttpResponseSubstitutionCallback(outputcache_callback);
Context.Response.WriteSubstitution(callback);
}
public static string outputcache_callback(HttpContext context)
{
string html = "";
html += "<script type='text/javascript'>";
html += " var lang='" + Project.Common.CurrentLang + " ';";
html += " var applicationPath='" + GetApplicationPath + "'; ";
html += "</script>";
return html;
}
public GetApplicationPath { get { ..logic.. }}
这是将脚本放入客户端的另一种技术。如果您将特定于用户或实例的变量加载到脚本中,则很好。 static
用于替换样本。此外,如果你想影响控件本身的内容生成(就像你要制作一个更聪明的asp:Label,你可以这样做,
public override void RenderControl(HtmlTextWriter writer)
{
base.RenderControl(writer);
writer.Write("<div id='dvBox'>");
....
base.RenderChildren(writer);
writer.Write("</div>");
writer.Write(script);
}
我希望这些信息可以结合并帮助几个开发人员在那里搜索构建控件的方法。