MVC4 StyleBundle不会呈现正确的顺序包 [英] MVC4 StyleBundle doesn't render the bundle in the correct order

查看:1608
本文介绍了MVC4 StyleBundle不会呈现正确的顺序包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想呈现的css文件捆绑,但输出是错误的顺序。我试着解决@ <一个href=\"http://stackoverflow.com/questions/9657412/mvc4-beta-minification-and-bundling-ordering-files-and-debugging-in-browser\">MVC4贝塔缩小与绑扎:订购文件和调试中的浏览器,但它并没有帮助。这里是束:

I'm trying to render a bundle of css files, but the output is in wrong order. I've tried the solution @ MVC4 Beta Minification and Bundling: Ordering files and debugging in browser , but it didn't help. Here is the bundle:

bundles.Add(new StyleBundle("~/stylesheet")
    .Include("~/css/main.css")
    .Include("~/css/mvc.css")
    .Include("~/js/jquery.thickbox.css")
    .Include("~/js/jquery.rating.css")
    .Include("~/css/ProductListing.css")
    .Include("~/css/dropdown/dropdown.css")
    .Include("~/css/dropdown/dropdown.vertical.css")
    .Include("~/js/fancybox/jquery.fancybox-1.3.1.css")
    .Include("~/css/scartpopup.css")
    .Include("~/css/ShoppingCart.css")
    .Include("~/css/ceebox.css")
    .Include("~/css/tooltip.css")
    .Include("~/css/recent_blog_posts.css")
    .Include("~/css/ProductDetail.css")
    .Include("~/css/jquery-ui-1.7.3.custom.css")
    .Include("~/css/filter_box.css")
    .Include("~/css/custom_page.css")
    .Include("~/css/Checkout.css")
    .Include("~/css/CheckoutButton.css")
);

这是结果,你可以看到了jQuery的UI来顶。

And here is the result, as you can see the jquery-ui comes to top.

<link href="/css/jquery-ui-1.7.3.custom.css" rel="stylesheet"/>
<link href="/css/main.css" rel="stylesheet"/>
<link href="/css/mvc.css" rel="stylesheet"/>
<link href="/js/jquery.thickbox.css" rel="stylesheet"/>
<link href="/js/jquery.rating.css" rel="stylesheet"/>
<link href="/css/ProductListing.css" rel="stylesheet"/>
<link href="/css/dropdown/dropdown.css" rel="stylesheet"/>
<link href="/css/dropdown/dropdown.vertical.css" rel="stylesheet"/>
<link href="/js/fancybox/jquery.fancybox-1.3.1.css" rel="stylesheet"/>
<link href="/css/scartpopup.css" rel="stylesheet"/>
<link href="/css/ShoppingCart.css" rel="stylesheet"/>
<link href="/css/ceebox.css" rel="stylesheet"/>
<link href="/css/tooltip.css" rel="stylesheet"/>
<link href="/css/recent_blog_posts.css" rel="stylesheet"/>
<link href="/css/ProductDetail.css" rel="stylesheet"/>
<link href="/css/filter_box.css" rel="stylesheet"/>
<link href="/css/custom_page.css" rel="stylesheet"/>
<link href="/css/Checkout.css" rel="stylesheet"/>
<link href="/css/CheckoutButton.css" rel="stylesheet"/>

我怎样才能确保样式表以正确的顺序呈现?

How can I make sure that the stylesheets are rendered in correct order?

推荐答案

不应该捆绑呈现在完全相同的顺序CSS文件,它遵循不同的逻辑。如果你需要使它们的定义,那么你应该创建一个自定义的<一个href=\"http://msdn.microsoft.com/en-us/library/system.web.optimization.ibundleorderer.aspx\">IBundleOrderer并将其设置为束作为所需订户

Bundling is not supposed to render the CSS files in the exact same order, it follows a different logic. If you need to render them as defined, then you should create a custom IBundleOrderer and set it to the bundle as the required Orderer:

public class AsDefinedBundleOrderer : IBundleOrderer
{
    public IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files)
    {
        return files;
    }
}

var bundle = new StyleBundle("~/stylesheet");
bundle.Orderer = new AsDefinedBundleOrderer();
bundles.Add(bundle);

那么这将什么也不做的列表,以便将渲染正好使它们以相同的顺序。

Then this will do nothing with the list so Render will render them exactly in the same order.

这是默认的排序的更新

捆绑使用 IBundleOrderer 的理念,以捆绑中的项目进行排序。
捆绑类都有它看起来像这样订货人属性:

Bundling uses the concept of IBundleOrderer to sort the items within a Bundle. The Bundle class has it's Orderer property which looks like this:

public IBundleOrderer Orderer
{
  get
  {
    if (this._orderer == null)
      return (IBundleOrderer) DefaultBundleOrderer.Instance;
    else
      return this._orderer;
  }
  set
  {
    this._orderer = value;
    this.InvalidateCacheEntries();
  }
}

所以默认订货人实际上是一个 DefaultBundleOrderer ,直到你与你的自定义订购者覆盖。

So the default orderer is actually a DefaultBundleOrderer until you overwrite it with your custom orderer.

IBundleOrderer 具有以下签名:

public interface IBundleOrderer
{
  IEnumerable<FileInfo> OrderFiles(BundleContext context, IEnumerable<FileInfo> files);
}

DefaultBundleOrderer 执行此订单减少文件的的BundleContext ,这里是从执行一个片段 OrderFiles

The DefaultBundleOrderer implementation of this orders the files by the BundleContext, here is a snippet from the implementation of OrderFiles:

  foreach (BundleFileSetOrdering ordering in (IEnumerable<BundleFileSetOrdering>) context.BundleCollection.FileSetOrderList)
    DefaultBundleOrderer.AddOrderingFiles(ordering, (IEnumerable<FileInfo>) list, fileMap, foundFiles, result);

因此​​,不同的结果发生,因为这一点。这当然不是一个随机排序算法的:)
这些规则在 BUndleCollection 类中定义的:

public static void AddDefaultFileOrderings(IList<BundleFileSetOrdering> list)
{
  if (list == null)
    throw new ArgumentNullException("list");
  BundleFileSetOrdering bundleFileSetOrdering1 = new BundleFileSetOrdering("css");
  bundleFileSetOrdering1.Files.Add("reset.css");
  bundleFileSetOrdering1.Files.Add("normalize.css");
  list.Add(bundleFileSetOrdering1);
  BundleFileSetOrdering bundleFileSetOrdering2 = new BundleFileSetOrdering("jquery");
  bundleFileSetOrdering2.Files.Add("jquery.js");
  bundleFileSetOrdering2.Files.Add("jquery-min.js");
  bundleFileSetOrdering2.Files.Add("jquery-*");
  bundleFileSetOrdering2.Files.Add("jquery-ui*");
  bundleFileSetOrdering2.Files.Add("jquery.ui*");
  bundleFileSetOrdering2.Files.Add("jquery.unobtrusive*");
  bundleFileSetOrdering2.Files.Add("jquery.validate*");
  list.Add(bundleFileSetOrdering2);
  BundleFileSetOrdering bundleFileSetOrdering3 = new BundleFileSetOrdering("modernizr");
  bundleFileSetOrdering3.Files.Add("modernizr-*");
  list.Add(bundleFileSetOrdering3);
  BundleFileSetOrdering bundleFileSetOrdering4 = new BundleFileSetOrdering("dojo");
  bundleFileSetOrdering4.Files.Add("dojo.*");
  list.Add(bundleFileSetOrdering4);
  BundleFileSetOrdering bundleFileSetOrdering5 = new BundleFileSetOrdering("moo");
  bundleFileSetOrdering5.Files.Add("mootools-core*");
  bundleFileSetOrdering5.Files.Add("mootools-*");
  list.Add(bundleFileSetOrdering5);
  BundleFileSetOrdering bundleFileSetOrdering6 = new BundleFileSetOrdering("prototype");
  bundleFileSetOrdering6.Files.Add("prototype.js");
  bundleFileSetOrdering6.Files.Add("prototype-*");
  bundleFileSetOrdering6.Files.Add("scriptaculous-*");
  list.Add(bundleFileSetOrdering6);
  BundleFileSetOrdering bundleFileSetOrdering7 = new BundleFileSetOrdering("ext");
  bundleFileSetOrdering7.Files.Add("ext.js");
  bundleFileSetOrdering7.Files.Add("ext-*");
  list.Add(bundleFileSetOrdering7);
}

所以,当你调用这个的Application_Start

BundleConfig.RegisterBundles(BundleTable.Bundles);

其实你通过默认的 BundleCollection 在库中定义的。

因此​​,我们必须通过一个接一个到 BundleFileSetOrdering 实例:

So we have the BundleFileSetOrdering instances passed one-by-one into:

private static void AddOrderingFiles(BundleFileSetOrdering ordering, IEnumerable<FileInfo> files, Dictionary<string, HashSet<FileInfo>> fileMap, HashSet<FileInfo> foundFiles, List<FileInfo> result)
{
  foreach (string key in (IEnumerable<string>) ordering.Files)
  {
    if (key.EndsWith("*", StringComparison.OrdinalIgnoreCase))
    {
      string str = key.Substring(0, key.Length - 1);
      foreach (FileInfo fileInfo in files)
      {
        if (!foundFiles.Contains(fileInfo) && fileInfo.Name.StartsWith(str, StringComparison.OrdinalIgnoreCase))
        {
          result.Add(fileInfo);
          foundFiles.Add(fileInfo);
        }
      }
    }
    else if (fileMap.ContainsKey(key))
    {
      List<FileInfo> list = new List<FileInfo>((IEnumerable<FileInfo>) fileMap[key]);
      list.Sort((IComparer<FileInfo>) FileInfoComparer.Instance);
      foreach (FileInfo fileInfo in list)
      {
        if (!foundFiles.Contains(fileInfo))
        {
          result.Add(fileInfo);
          foundFiles.Add(fileInfo);
        }
      }
    }
  }
}

结论

如果我们想要简化这个过程,我们可以说,库prefers某些类型的文件,并就其他文件的一些排序,如果发现多种可能性。这是预期的行为的大部分时间,但你可以看到它是用 AsDefinedBundleOrderer 所以它什么都不设置指定的文件,因此为了保持原来的伊斯利重写。

If we want to simplify the process we can say that the library prefers some kind of files and makes some sorting on the other files if multiple possibilities found. This is the expected behavior most of the time but as you can see it is easly overridable with the AsDefinedBundleOrderer so it does nothing with the given file set so the order remains the original.

这篇关于MVC4 StyleBundle不会呈现正确的顺序包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆