- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
约束:我没有使用 MVC,只是在我的 Web 应用程序中使用常规的 ol'.aspx 文件。也不使用母版页 - 每个页面都是不同的野兽,因此该解决方案不适合我。
我读过的关于捆绑和缩小的大多数示例都需要一些特殊的 MVC 标记,或者要求您预先识别捆绑的脚本/样式表,然后引用这些 bundle 。我想避免每次在 .aspx 页面中添加或修改 .js 引用时都重新编译 DLL。
我对阅读 Msft 文档有点困惑.. 有没有一种方法(比如 ASP.NET 控件)我可以只包装一系列 script
标签(或 链接 CSS 的
标签)来动态地创建和使用一个包?我不想重新发明轮子,而是认真考虑创建我自己的用户控件/自定义控件来处理这个问题。还有其他选择吗?
例如,寻找这样的东西:
<asp:AdHocScriptBundle id="mypage_bundle" runat="server">
<script type="text/javascript" src="~/scripts/mypage1.js"></script>
<script type="text/javascript" src="~/scripts/mypage2.js"></script>
<script type="text/javascript" src="~/scripts/mypage3.js"></script>
</asp:AdHocScriptBundle>
当启用捆绑时,自动将 asp:AdHocScriptBundle
的内容替换为单个 script
标记,类似于:
<script type="text/javascript" src="/webappname/bundles/mypage_bundle.js?v=dh120398dh1298dh192d8hd32d"></script>
当禁用 Bundling 时,通常会像这样输出内容:
<script type="text/javascript" src="/webappname/scripts/mypage1.js"></script>
<script type="text/javascript" src="/webappname/scripts/mypage2.js"></script>
<script type="text/javascript" src="/webappname/scripts/mypage3.js"></script>
有什么想法吗?
无论如何我都会自己动手,但是如果已经有解决方案请分享,谢谢!
最佳答案
我推出了自己的解决方案,效果很好!我创建了 4 个可用作自定义服务器控件的类:
这些调用函数围绕我的自定义捆绑库,它本身是 System.Web.Optimization API 的包装器。
在 ScriptBundle
和 StyleBundle
的渲染过程中,我然后检查一个内部设置(与我在 System. Web.Optimization API)告诉页面要么使用捆绑,要么简单地写出正常的 script
/link
标签。如果启用了捆绑,它会从我的自定义捆绑库中调用此函数(对于脚本,样式的类似代码。下面代码中的 Bundler
是我的自定义捆绑库的类 - 以防万一 Microsoft 更改系统.Web.Optimization API 我想要一个介于两者之间的层,这样我就不必更改我的代码太多):
public static void AddScriptBundle(string virtualTargetPath, params string[] virtualSourcePaths)
{
var scriptBundle = new System.Web.Optimization.ScriptBundle(virtualTargetPath);
scriptBundle.Include(virtualSourcePaths);
System.Web.Optimization.BundleTable.Bundles.Add(scriptBundle);
}
为了确保我只创建尚不存在的 Bundle,我首先使用此方法检查 Bundle(在使用上述方法之前):
public static bool BundleExists(string virtualTargetPath)
{
return System.Web.Optimization.BundleTable.Bundles.GetBundleFor(virtualTargetPath) != null;
}
然后我使用此函数通过 System.Web.Optimization 吐出 bundle 的 URL:
public static System.Web.IHtmlString GetScriptBundleHTML(string virtualTargetPath)
{
return System.Web.Optimization.Scripts.Render(virtualTargetPath);
}
在我的 .aspx 文件中,我这样做:
<%@ Register TagPrefix="cc1" Namespace="AdHocBundler" Assembly="AdHocBundler" %>
...
<cc1:ScriptBundle name="MyBundle" runat="Server">
<cc1:script src='~/js/script1.js'/>
<cc1:script src='~/js/utils/script2.js'/>
</cc1:ScriptBundle>
我的诀窍是弄清楚我必须将 script
和 link
标签转换为 ScriptBundle
中的列表项,并且StyleBundle
控件,但之后效果很好,它让我可以使用波浪号运算符轻松引用应用程序根目录(使用 Page.ResolveClientUrl()
,这有助于创建模块内容)。
感谢转到此 SO 答案帮助我弄清楚如何创建自定义集合控件:How do you build an ASP.NET custom control with a collection property?
更新:为了全面披露,我获得了共享 ScriptBundle 代码的许可(StyleBundle 几乎相同,因此没有包含它):
[DefaultProperty("Name")]
[ParseChildren(true, DefaultProperty = "Scripts")]
public class ScriptBundle : Control
{
public ScriptBundle()
{
this.Enabled = true;
this.Scripts = new List<Script>();
}
[PersistenceMode(PersistenceMode.Attribute)]
public String Name { get; set; }
[PersistenceMode(PersistenceMode.Attribute)]
[DefaultValue(true)]
public Boolean Enabled { get; set; }
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public List<Script> Scripts { get; set; }
protected override void Render(HtmlTextWriter writer)
{
if (String.IsNullOrEmpty(this.Name))
{
// Name is used to generate the bundle; tell dev if he forgot it
throw new Exception("ScriptBundle Name is not defined.");
}
writer.BeginRender();
if (this.Enabled && Bundler.EnableOptimizations)
{
if (this.Scripts.Count > 0)
{
string bundleName = String.Format("~/bundles{0}/{1}.js",
HttpContext.Current.Request.FilePath,
this.Name).ToLower();
// create a bundle if not exists
if (!Bundler.BundleExists(bundleName))
{
string[] scriptPaths = new string[this.Scripts.Count];
int len = scriptPaths.Length;
for (int i = 0; i < len; i++)
{
if (!string.IsNullOrEmpty(this.Scripts[i].Src))
{
// no need for resolve client URL here - bundler already does it for us, so paths like "~/scripts" will already be expanded
scriptPaths[i] = this.Scripts[i].Src;
}
}
Bundler.AddScriptBundle(bundleName, scriptPaths);
}
// spit out a reference to bundle
writer.Write(Bundler.GetScriptBundleHTML(bundleName));
}
}
else
{
// do not use bundling. generate normal script tags for each Script
foreach (Script s in this.Scripts)
{
if (!string.IsNullOrEmpty(s.Src))
{
// render <script type='<type>' src='<src'>/> ... and resolve URL to expand tilde, which lets us use paths relative to app root
// calling writer.Write() directly since it has less overhead than using RenderBeginTag(), etc., assumption is no special/weird chars in the cc1:script attrs
writer.Write(String.Format(Script.TAG_FORMAT_DEFAULT,
s.Type,
Page.ResolveClientUrl(s.Src)));
}
}
}
writer.EndRender();
}
}
public class Script
{
public const String ATTR_TYPE_DEFAULT = "text/javascript";
public const String TAG_FORMAT_DEFAULT = "<script type=\"{0}\" src=\"{1}\"></script>";
public Script()
{
this.Type = ATTR_TYPE_DEFAULT;
this.Src = null;
}
public String Type { get; set; }
public String Src { get; set; }
public String Language { get; set; }
}
关于javascript - 如何在不重新编译的情况下使用 ASP.NET 捆绑和缩小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17437800/
我是一名优秀的程序员,十分优秀!