I have 3 views in my MVC5 App. Say A,B,C and 3 javascript files A.js, B.js C.js
When appropriate view is loaded, I want appropriate javascript files to get loaded. I do not want all files to get loaded at the start up.
How do I achieve that?
In ViewA, add the following
#scripts {
<script src="A.js"></script>
}
In ViewB, add the following
#scripts {
<script src="B.js"></script>
}
and so on...
If you are using a _Layout.cshtml, make sure you have the proper RenderSection:
#RenderSection("scripts", required: false)
then in the views itself do this:
#section scripts {
<script src="B.js"></script>
}
Related
My website has two kind of pages:
Pages where javascript widgets are the main content of the page (TypeA) and where widgets are some additional content, that user might to trigger (TypeB).
So I'd like to split my JS codebase into three bundles:
vendor.js -- which is included on all pages
runtime.js -- for widgets
specific entry points for different pages
For TypeA-pages I have this:
<script src="vendor.js"></script>
<script src="runtime.js"></script>
<script src="pageA.js"></script>
<!-- pageA.js launches the widget -->
But for TypeB I want this:
<script src="vendor.js"></script>
<scriprt>
<!-- pseudo code -->
when('user clicks button', function() {
require.ensure('pageB.js', function(require) {
var pageBCode = require('pageB.js');
<!-- do the magic -->
<!-- but I also need runtime.js here -->
});
});
</script>
The problem is, that I want to reuse runtime.js in both sync and async pages. But I can't figure out how to load runtime.js along with my on-demand loading pageB.js. I still have to include it via <script src="runtime.js"></script>.
(I use CommonChunksPlugin for creating vendor.js and runtime.js, and it works well on TypeA pages)
You can pass an array to require.ensure as such:
require.ensure(['pageB.js','runtime.js'], function(require){
var pageBCode = require('pageB.js'),
runtimeCode = require('runtime.js');
/** MAGIC! **/
});
strong textIn my ASP MVC 5 app, I have a (master - Jquery loads here) _layout.cshtml and (child, my function sortable here, not loading) views tableView.cshtml
In the child tableView.cshtml, I've written custom JS functions that need to be invoked on Jquery Read $ ready. Since jquery has already loaded in the master page, how can I attach my function (and 3rd parts plugins) invoke it when my child page loads?
if possible, please share a modular way to attach and initialize my functions and 3rd party plugins in the childviews on the child view loading/navigation load, so that when the main jquery function loads, it also invokes my functions.
_layout.cshtml
// DOM ready is completed in master layout, I have custom JS plugin/code (sortable)
// in the child view that I need to load, when that loads
$( document ).ready(function() {
console.log( "Master layout ready, done" );
});
TableView.cshtml
// in my tableView, that inherits layout from master,
// how can I get this loaded when the page loads
(function() {
console.log( "How can I get child table plugin, loaded!" );
})();
You should make use of #RenderSection() which act as placeholders to render content from the view
You layout page might look something like
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
.....
// Include common style sheets here
#RenderSection("styles", false) // placeholder for styles
#Scripts.Render("~/bundles/modernizr")
</head>
<body>
....
#RenderBody()
....
// Include all common scripts here
#Scripts.Render("~/bundles/jquery") // include jquery first
#RenderSection("scripts", required: false) // placeholder for page specific scripts
</body>
</html>
and in the view
#model YourModel
// html here
....
#section styles {
<link href="~/Content/PageSpecificStyleSheet.css" rel="stylesheet" />
}
#section scripts {
// Add page specific scripts and plugin files here
#Scripts.Render("~/bundles/jqueryval")
<script src="../../Scripts/MyScript.js" type="text/javascript"></script>
....
<script type="text/javascript">
// Other javascript code here
</script>
}
Note #RenderSection("styles", false) is in the <head> element and #RenderSection("scripts", required: false) is immediately before the closing </body> tag meaning any scripts defined in the view will be loaded after the page elements have loaded (and after the jquery file)
What is the difference between the following 2 Javascripts? I can use the second form of Javascript in Razor engine MVC pages without any issues, so what is the benefit of using the first form?
MVC style
#section Scripts {
function check()
{
//do some validation logic here
}
}
WebForms style
<script type="text/javascript">
function check()
{
//do some validation logic here
}
</script>
The #section Scripts doesn't produce any output in the page on its own, you need to render the section somewhere. When you use it, there is a RenderSection call somewhere, like this:
<script type="text/javascript">
#RenderSection('Scripts')
</script>
The fact that the section is named Scripts doesn't have any relevance, it's just a convention that is used for sections that contain scripts.
#section Scripts { is acting like place holder for your scripts. In your layout page you would include the following
<!DOCTYPE html>
<html>
<head>
....
</head>
<body>
// common html for all pages based on this layout
#RenderSection("scripts", required: false)
</body>
This is saying, that if the page includes the section Scripts, then render it here. So your page that uses this layout might have the following
#section scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="../../Scripts/YourScript.js" type="text/javascript"></script>
<script type="text/javascript">
$('#SomeElement').click(function() {
// do something
});
</script>
}
and #RenderSection("scripts", required: false) would be replaced by whats in the #section scripts {
This may work, but won't be ideal for one reason:
#section Scripts {
function check()
{
//do some validation logic here
}
}
Will cause you to lose intellisense. It may work, but will make life more difficult. It's often best to include the script tag:
#section Scripts {
<script type="text/javascript">
function check()
{
//do some validation logic here
}
</script>
}
Also #section scripts renders where a #RenderSection("Scripts") is defined in the master page. Without it, it renders EXACTLY where the script tag you have (in your WebForms example).
I am using requireJS for my hybrid app . Now I need to change the script tag located into my layout page with conditions on url . The script tag looks something like this
<script data-main="#Url.Content("~/Scripts/main")" src="#Url.Content("~/Scripts/Libs/Requirejs/require.min.js")" type="text/javascript"></script>
Now when the page loads the /Home/Login the script tag above should be changed to
<script data-main="#Url.Content("~/Scripts/login")" src="#Url.Content("~/Scripts/Libs/Requirejs/require.min.js")" type="text/javascript"></script>
Again when I load the page /Mail/Index The script tag above should change to
<script data-main="#Url.Content("~/Scripts/mail")" src="#Url.Content("~/Scripts/Libs/Requirejs/require.min.js")" type="text/javascript"></script>
Now Note that All of the three pages uses the same **_Layout.cshtml** page . And the above script tag is located in **_Layout.cshtml** page only .Now how do I track this scripts to change the script tag on change of the Url routing as mentioned above ?
I'd simply use a section for this. In the layout page:
#RenderSection("RequireScripts")
And put the script in each page:
#section RequireScripts {
<script data-main="#Url.Content("~/Scripts/main")" src="#Url.Content("~/Scripts/Libs/Requirejs/require.min.js")" type="text/javascript"></script>
}
If you're after a way to avoid re-writing the whole thing (only requiring the relative path), then I suppose you could make use of the dynamic Page variable:
#if (Page.RequireScript != null)
{
<script src='~/Scripts/#Page.RequireScript'></script>
}
Then the script block would get output to pages that define RequireScript.
#{
Page.RequireScript = "Libs/Requirejs/require.min.js";
}
In a partial view I load a javascript file like this :
<script src="#Url.Content("~/Scripts/Testing.js")" type="text/javascript"></script>
In the Testing.js, there are some functons defined
That's work, the functions defined in the file can be used.
Now I do an action in my application, my controller return an another (where I don't load any js file) partial view. The functions defined in Testing.js are still available in this partial view.
Is there a way to "remove" the functions loaded in the first view ?
Thanks,
Update 1
I tried this in the partial view but error :
The file "~/Views/xxxx.cshtml" cannot be requested directly because it calls the "RenderSection" method.
#section MyScript {
<script src="#Url.Content("~/Scripts/Testing.js")" type="text/javascript"></script>
}
#RenderSection("MyScript", false)
You should avoid referencing any scripts in partials. You could define a section in your Layout, for example just before the closing </body> which will allow for views to include some custom scripts:
<script type="text/javascript" src="#Url.Content("~/scripts/some_common_script_that_will_be_used_by_all_views_such_as_jquery_for_example")"></script>
#RenderSection("scripts", false)
</body>
</html>
and then in the view (not in the partial view) override this section to include any scripts that this view might need:
#section scripts {
<script src="#Url.Content("~/Scripts/Testing.js")" type="text/javascript"></script>
}