ScriptBundle dependencies - asp.net-mvc-4

I'm having difficulties getting the ScriptBundle to work properly (if this is supposed to work at all). What I'm trying to do is add another bundle (jQuery) as a dependency to my bundle, like so:
bundles.Add(new ScriptBundle("~/js/myscripts")
.Include("~/js/jquery",
"~/Content/scripts/myscript.js"));
~/js/jquery is the "name" (virtual path) of the jQuery bundle, registered as so (before my dependent bundle):
bundles.Add(new ScriptBundle("~/js/jquery")
.Include("~/Content/scripts/jquery-{version}.js"));
When I do #Scripts.Render("~/js/myscripts") in my view, only myscript.js is rendered to the HTML. If I change the virtual path to jQuery from the one in the name of the bundle to the physical, existing one, it works:
bundles.Add(new ScriptBundle("~/js/myscripts")
.Include("~/Content/scripts/jquery-{version}.js",
"~/Content/scripts/myscript.js"));
Also, doing #Scripts.Render("~/js/jquery") in the view, works. It's just referencing the non-existing virtual path (name) of another ScriptBundle that doesn't work. Is this supposed to work at all? If not, I would like to know where I can post a bug report saying that this scenario should throw an exception if it's not supported. If it is supported, where does it say and why doesn't it work?

Going by what your dependency all you have to put in your layout (view) is
#Scripts.Render("~/js/jquery")
#Scripts.Render("~/js/myscripts")
Update after your comment:
You cannot nest bundles, that is you can't Include a bundle within a bundle, that virtual path is most likely not available while the parent bundle is being created.
Typically I have a separate jquery bundle (including some other infrequently changing js) anyway and then one other js bundle for everything else. works well for browser caching.
On a side note, have you looked at requireJS, which is not really needed if you are bundling everything but it does make your js files better documented as it makes the dependencies explicit

It's not supported, but you could come up with your own solution to this, right? Something like:
var jquery = new[] { "~/Content/scripts/jquery-{version}.js" };
var myScripts = jquery.Concat(new[] { "~/Content/scripts/myscript.js" }).ToArray();
var myOtherScripts = myScripts.Concat(new[] { "~/Content/scripts/otherscript.js").ToArray();
bundles.Add(new ScriptBundle("~/js/jquery").Include(jquery));
bundles.Add(new ScriptBundle("~/js/myscripts").Include(myScripts));
bundles.Add(new ScriptBundle("~/js/other").Include(myOtherScripts));

Seems like this is an unsupported feature, so I've reported an issue for it.

Related

Sencha Touch testing build not working

I've finished my first app using sencha touch 2.2.1. Now I uploaded it onto my server and tried to access it with my phone. Everything works well. My Dashboard contains 6 buttons, but only 1 of them is working. Each other throws the following error
TypeError: 'undefined' is not an object (evaluating 'name.substring')
The error occurs in the function parseNamespace. But I don't know what is wrong. I build the app using Sencha Architect and in the preview everything was fine. The testing package was created using the build-button from architect. If anyone could help me, the app is located here: app.ttv-rees-groin.de
Many thanks
This may be issue with class loading. The classes which are referred in the event of button events may not be loaded at the time.
Those classes may be missed when packaging application.
My experience found that Architect's build and package tools created a bloated mess of unnecessary files far exceeding what was required. Technical details: Architect 2 - all builds, Sencha Touch 2.0-2.2.x including all versions in between, Sencha Cmd 3.x
The cleanest and leanest build technique for developing in Architect was to save then fire the build using Sencha Cmd.
sencha app build
This performs the default "production" build.
The difference in output in this case went from a 32MB dump of files in the production folder with all resources, library, extensions etc, to the minimum required files totalling 0.8MB, and no longer requiring the touch library as only the classes needed were compiled into the app.
As for the error at hand, this error has something to do with class namespace, alias and xtype.
(Quick thanks to http://ruidevnotes.wordpress.com/2013/07/25/sencha-ext-js-4-common-typeerror/, saving me quite a lot of typing for these 4 things to check).
Possible solutions:
If class has controller, make sure the controller’s views config match the namespace specified on the class view’s Ext.define. Example: (controller)
views : ['namespace.of.my.View']
When using class on other view as xtype, make sure view’s alias is
widget.[customXtype]
so when adding it as an item to other viems, use
xtype : [customXtype]
Make sure view’s controller is added on app.js controllers.
When class view has no controller and you wanted to use it on other views, make sure to add the namespace of that view on
Ext.require(['class.view.namespace.name']);
and specify the xtype config instead of alias.
On top of these points, I recall an issue with list plugins, that I believe behaves identical to the error you are encountering. Prebuild - would work. Post build, issues and errors. The way I was able to get around this error was via this technique:
requires: [
'Ext.XTemplate',
'Ext.plugin.ListPaging'
],
config: {
..., // other standard configs removed for brevity
plugins: [
{
xclass: 'Ext.plugin.ListPaging',
autoPaging: true,
type: 'listpaging'
}
]
}
The thing to note is the exaggerated plugins declaration. Without this comprehensive declaration, the ListPaging plugin caused all manner of pain and chaos, and solely after a build.
EDIT: spelling.

What is Styles.render equivalent for XSL/XSLT?

In MVC4 you can render CSS stles by using
Styles.Render(path here)
Similarly scripts can be rendered by
Scripts.Render(path here)
But how do render XSL/XSLT stylesheets? Will Styles.Render do the trick?
The reason you do #Styles.Render or #Scripts.Render is because it references a bundle created somewhere in Global.asax, usually in the BundleConfig (look in your App_Start folder). They are created using the code
bundles.Add(new StyleBundle("~/Content/themes/base/css").Include(
"~/Content/themes/base/jquery.ui.core.css",
"~/Content/themes/base/jquery.ui.resizable.css"...
so then you can use them in your views as #Styles.Render("~/Content/themes/base/css"). The framework actually creates a virtual file with the path "~/Content/themes/base/css" to enable this bundling technology.
I dont think the stylebundle can be used with xsl/xslt stylesheets, although I dont know for sure. Here are some relevant question to boot.
How to apply an XSLT Stylesheet in C#
or any of these really
https://stackoverflow.com/questions/tagged/xslt+asp.net-mvc

Referencing other bundles in BundleConfig.cs in ASP.NET MVC4 app

I am working on an MVC4 application where I'm using WebOptimization to do all of my resource handling (cat and min). I have a few pages which are very similar, but need a few varying styles on a page by page basis.
So, I am trying to reference one bundle (base styles) within another bundle (page specific styles) and I'm not having much luck. Here's what I have in my bundle config:
bundles.Add(new StyleBundle("~/bundles/css/search").Include(
"~/Content/css/partials/grid-controls.css",
"~/Content/css/partials/grid.css",
"~/Content/css/views/search.css"));
bundles.Add(new StyleBundle("~/bundles/css/searchtrees").Include(
"~/bundles/css/search",
"~/Content/css/views/search/trees.css"));
On the search trees page I get the trees.css but nothing from the base search CSS bundle.
How can I go about referencing the first bundle in the second? I'm sure there's a way, just not too familiar with bundling yet.
You can reuse the file references instead of referencing another bundle. Something like this:
var baseIncludes = new string [] { "~/Content/css/partials/grid-controls.css", "~/Content/css/partials/grid.css", "~/Content/css/views/search.css" };
// 'base' bundle references the base includes
bundles.Add (new StyleBUndle ("~/bundles/css/search").Include (baseIncludes));
// other bundle references the base includes and some extras
bundles.Add (new StyleBundle ("~/bundles/css/searchtrees").Include(baseIncludes).Include ("~/Content/css/views/search/trees.css"));

ASP.NET MVC 4 ScriptBundle returns empty

Specifically, I am trying to create a ScriptBundle in MVC 4 with already minified scripts, and return this same Bundle whether the project is in Debug or not.
My web project references the MVC Telerik Grid NuGet package. In that package, Telerik only provides the minified JS files. Bundling code is below.
// telerik scripts
bundles.Add(new ScriptBundle("~/scripts/bundles/telerik").Include(
"~/Scripts/2012.1.214/telerik.common.min.js",
"~/Scripts/2012.1.214/telerik.textbox.min.js",
"~/Scripts/2012.1.214/telerik.calendar.min.js",
"~/Scripts/2012.1.214/telerik.datepicker.min.js",
"~/Scripts/2012.1.214/telerik.grid.min.js",
"~/Scripts/2012.1.214/telerik.grid.filtering.min.js"));
Other ScriptBundles run fine, but when my project attempts to reference this bundle, the request appears as: scripts/bundles/telerik?v= Returning nothing.
If I set BundleTable.EnableOptimizations = true, then it DOES return the ScriptBundle and references a specific version, however this solution is unacceptable.
I do not want to forcibly set BundleTable.EnableOptimizations = true, since I want all other Bundles to return the non-minified versions when appropriate.
Anyone have a similar experience and if so, what was the solution?
I think you have the same problem, please look at this link: mvc4 bundler not including .min files
Either rename .min.js to .js or do something like:
public static void AddDefaultIgnorePatterns(IgnoreList ignoreList)
{
if (ignoreList == null)
throw new ArgumentNullException("ignoreList");
ignoreList.Clear();
ignoreList.Ignore("*.intellisense.js");
ignoreList.Ignore("*-vsdoc.js");
ignoreList.Ignore("*.debug.js", OptimizationMode.WhenEnabled);
//ignoreList.Ignore("*.min.js", OptimizationMode.WhenDisabled);
ignoreList.Ignore("*.min.css", OptimizationMode.WhenDisabled);
}

MEF + SL4 question

I'm working on an app in the Silverlight 4 RC and i'm taking the oppertunity to learn MEF for handling plugin controls. I've got it working in a pretty basic manor, but it's not exactly tidy and I know there is a better way of importing multiple xap's.
Essentially, in the App.xaml of my host app, I've got the following telling MEF to load my xap's:
AggregateCatalog catalog = new AggregateCatalog();
DeploymentCatalog c1 = new DeploymentCatalog(new Uri("TestPlugInA.xap", UriKind.Relative));
DeploymentCatalog c2 = new DeploymentCatalog(new Uri("TestPlugInB.xap", UriKind.Relative));
catalog.Catalogs.Add(c1);
catalog.Catalogs.Add(c2);
CompositionHost.Initialize(catalog);
c1.DownloadAsync();
c2.DownloadAsync();
I'm sure I'm not using the AggregateCatalog fully here and I need to be able to load any xap's that might be in the directory, not just hardcoding Uri's obviously....
Also, in the MainPage.xaml.cs in the host I have the following collection which MEF puts the plugin's into:
[ImportMany(AllowRecomposition = true)]
public ObservableCollection<IPlugInApp> PlugIns { get; set; }
Again, this works, but I'm pretty sure I'm using ImportMany incorrectly....
Finally, the MainPage.xaml.cs file implements IPartImportsSatisfiedNotification and I have the following for handling the plugin's once loaded:
public void OnImportsSatisfied()
{
sp.Children.Clear();
foreach (IPlugInApp plugIn in PlugIns)
{
if (plugIn != null)
sp.Children.Add(plugIn.GetUserControl());
}
}
This works, but it seems filthy that it runs n times (n being the number of xap's to load). I'm having to call sp.Children.Clear() as if I don't, when loading the 2 plugin's, my stack panel is populated as follows:
TestPlugIn A
TestPlugIn A
TestPlugIn B
I'm clearly missing something here. Can anyone point out what I should be doing?
Thanks!
I think most of what you are doing is fine. Although ObservableCollections do support notifications of individual elements being added and removed, MEF doesn't take advantage of this. In your case it will simply clear the collection and then add all the plugins. Since you are using OnImportsSatisfied for the change notification, you don't even need an ObservableCollection. You could just use an IEnumerable for your import.
To add flexibility in downloading different xaps, I would expose a service in your container that can be imported and that provides the functionality to download a xap given a url. Then any component in your container can trigger a download, and the url to download can come from whatever source you deem appropriate.