So, continuing in climbing my MVC learning curve, I would like to know how to effectivelly handle javascript in partial views. I mean coding a script in a partial view and then rendering the partial view twice in a view gives duplicate code, including variables and is generally conflictive.
How pros handle JS concurrency in ASP.NET MVC so each partial view see only its own JS code?
When you render a partial view within a view, you can still reference all of the HTML elements in that partial view from Javascript on the holding view.
This will not only help with duplication, but will add to the principle that code should be maintainable within one place in the codebase.
If I were you, I would put all Javascript that your partial views need in the main view, or better yet, in a Javascript file that is separate and reference it in a master page which your main view inherits from :)
This video gave me a great inside look into jquery with mvc it share also some best-practise...
mvcConf 2 - Eric Sowell: Evolving Practices in Using jQuery and Ajax in ASP.NET MVC Applications
http://channel9.msdn.com/Series/mvcConf/mvcConf-2-Eric-Sowell-Evolving-Practices-in-Using-jQuery-and-Ajax-in-ASPNET-MVC-Applications
def. worth a look...
Use external javascript file and reference it only in the full view. Put this line in the partial view so it does not load the stuff from the _Layout.cshtml
#{ this.Layout = null; }
you need to add the script at the bottom of the page before close the body tag place all required js their and place a rendersection('yoursection',false) so when you need you can define your section and just use the script their who would work in the page you need to define.
If you want javascript need to maintained effectively. Write that javascript in seperate js file. create another partial view and give the link to the js file. while rendering partial views, render the partial view which contains the link for that js file
I am not sure if it is the best way of doing this, but I certainly got it working for me.
So you write you javascript in an external file, and reference it in a partial view, then you could nest your partial view inside this partial view, so each of those nested partial view will be able to use the java script file on their parent level. So this way, you only reference the javascript once, but it can be used with all nested partial views.
good luck mate.
I think Dan Finch and user2745484 have answered the question. But as you sad scripts in partial views may override each other. For solving these problem you need to use some kind of object oriented programming to have encapsulation. Note that you may encounter these kind of problem everywhere you write JavaScript code.
Related
I use a .cshtml file to generate a dynamic .js file in an ASP.NET MVC controller. So the .js file never exists on disk, but only in memory at runtime. It works like this.
The browsers loads a javascript...
<script async src='http://example.com/script.js'></script>
...that is fetched from and generated by my MVC Controller endpoint:
[HttpGet]
[Route("script.js")]
public ActionResult GetScript()
{
// This takes a .cshtml template-file and returns a generated .js file
return new JavascriptViewResult(viewName, viewModel);
}
Is there a way to minify the resulting javascript file that is returned in runtime? I had a look at System.Web.Optimization.JsMinify but I'm not sure how I would get that to work. Can I write some kind of HttpHandler? Is there maybe a better approach to solve this problem?
I had a similar problem and after some searching some I came across this question. All you need to do is:
using Microsoft.Ajax.Utilities;
//...
string minifiedScript = new Minifier().MinifyJavaScript(yourJs);
I can't believe it was this simple, yet so hard to find.
P.S. It seems to be part of Microsoft Ajax Minifier library, but I don't remember ever installing it manually, so it's either part of MVC or comes with System.Web.Optimization.
I didn't notice the part about the JS being generated from a view. In that case using bundles might be a solution or rendering the view to a string (but I'm unfamiliar with how it's done in Spark view engine) before passing it to Minifier.MinifyJavaScript.
Edit: Another solution (albite somewhat convoluted) would be calling Minifier.MinifyJavaScript in the view and cramming the actual JS in a partial view. I don't know about Spark, but in Razor it's fairly easy to render a view to string from another view.
Im pretty much stuck, because i cant figure out how to "call" resource files in .js files. I have a login view, on this view i call MVC render method to generate script tag.
#Scripts.Render("~/Scripts/Login.js")
in my Login.js i have a variable :
var yes = "Resources.Resource.Yes";
which should be tranlated to Yes, or Ja, or anything else depends on which cultureInfo is set. Its pretty straight forward to do if i keep script files inside of my view, because then i just call #Resources.Rescource.Yes and it will work, but if script file is external, then it wouldnt work. How do i solve this?
The answer to this question would be largely opinion-based.
There are three main approaches i encountered working on various projects:
Localization handlers. You define the resources keys in javascript, in $(document).ready() you use ajax to get the localized values from a controller/httphandler dedicated to this and replace keyed text.
In-line js. Basically, you dump external .js and render scripts inside <script> tags in your views/pages.
Global variables. In the view your define global variables, like so:<script language="text/javascript">var myString='<%= Resources.MyString %>';</script>, then use the variable inside included .js.
Personally i prefer approach n 3 -> you can have a single place in code to create all variables and the page loads in one go.
I am trying to find a way to add content to a div that is defined in my application.html.haml file from individual view files. The reason I want to do this is because I have a sidebar that is always present and is defined in the template, but I would like to have content specific to each page included in the sidebar. Would this be done best with javascript or is there some ruby on rails trick that I can use to make this easier?
I would use the content_for helper (Rails Guide) (API).
In haml, this would look something like:
(layout template)
#sidebar= yield :sidebar
(page template)
-content_for :sidebar do
...your content here
If you work with professional designers who handle the views, it may be easier over the long term to have rather repetitive view code. Some people have a hard time searching through partials and "seeing" how they all fit together. I've found it easier with those people to let them manage the whole shebang and update more than one file if they need to. Optimal? Not to us as programmers, but designers are more often used to seeing most of the HTML in one or three files rather than 20. :)
use partials as much as possible to keep your code DRY
this link helps you
http://guides.rubyonrails.org/layouts_and_rendering.html
There are essentially 2 places to define JavaScript functions in Grails, directly in a element on the GSP, and within a separate javascript source file under /web-app/js (for example, application.js). We have defined a commonly reused javascript function within application.js, but we also need to be able to generate parts of the function dynamically using groovy code. Unfortunately, ${some groovy code} does not appear to be processed within separate javascript source files.
Is the only way to do this by defining the javascript function within a script tag on a GSP page, or is there a more general solution? Obviously we could define the javascript function in a script tag within a template GSP file which would be reused, but there is a lot of push to keep our javascript functions defined all together in one place (i.e. the external javascript source file). This has performance benefits as well (the javascript source files are usually just downloaded once by each client's browser, instead of reloading the same javascript functions within the source of every html page they visit). I have toyed around with the idea of breaking the function up into static and dynamic pieces, putting the static ones in the external source and putting the dynamic ones in the template GSP, then gluing them together, but this seems like an unnecessary hack.
Any ideas?
(edit: It may sound like the idea of dynamically generating parts of a JavaScript function, which is then downloaded once and used over and over again by the client, would be a bad idea. However, the piece which is "dynamic" only changes perhaps once a week or month, and then only very slightly. Mostly we just want this piece generated off the database, even if only once, instead of hard coded.)
An easy solution to keep your JavaScript unobtrusive is to create a JavaScriptController and map its actions "/js/*" by adding this to your UrlMappings.groovy file:
"/js/$action"{
controller = "javascript"
}
then just create an action for each dynamic JS file you want, include in in your layout <HEAD>, and presto, you've got a JS file that you can insert Grails snippets into! :)
Note: I've found that there's currently a bug in Grails that doesn't map file extensions to content-types properly, so you'll need to include <%# page contentType="text/javascript; UTF-8" %> at the top of your view files.
This is a great solution. I would like to offer a suggestion to use somthing other then a mapping of "/js/$action" because this is no longer going to allow you to access you javascript files in /web-app/js/. All your javascript files would have to be moved to a the directory your controller would point to.
I would use something like
"/dynjs/$action"
This way you still can point to files in the /web-app/js/ files with out conflict and enjoy the benifits of gsp tags in javascript files
Please correct me if I'm wrong.
Or this... have a tag/service/dynamic method that lets tags write out their JS+CSS+whatever else, to a "cache" which is used to build the JS+CSS resources by a different controller.
Full concept here: [http://www.anyware.co.uk/2005/2009/01/19/an-idea-to-give-grails-tags-esp/][1]
If you want to use models created by the controller (that rendered HTML page which reference the Javascript in which you intend to use groovy code) in the Javascript code, then you can use this technique:
This technique does not need to change URL mappings and does not require you to create extra controller.
In your view GSP add javascript as follows:
<script type="text/javascript">
<g:render template="/javascript/yourJavascriptFile"/>
</script>
In views folder create a "javascript" folder. And create a file named:
_yourJavascriptFile.gsp
You can not only use all the GSP code in your _yourJavascriptFile.gsp file, but you can also use all the models created in your controller (that is rendering the view).
NOTE: There is nothing special about javascript folder. You can name it anything you want OR use an existing view folder. This is just a matter of organizing and identifying your HTML spitting GSP from Javascript spitting GSPs. Alternatively, you can use some naming conventions like: _something.js.gsp etc.
Name your scripts like this
/wherever/the/js/files/are/thescript.js.gsp
The gsp code inside will be rendered correctly by grails. This works, but I have no idea if it's considered a Good Idea or not.
There is another way - pass in the generated code into a function that expects closures. Those closures is generated by the program of course. The generated code is of course inlined/script-tagged in the gsp page.
it may or may not work depending on the nature of the code being generated. But i suspect it will work, and if it doesnt, minor tweaking to the coding style of your javascript will definitely make it work. Though, if these 'generated' code doesnt change much, this quite overkill imo.
I've a couple of extension methods I've been developing for a couple of projects, they currently rely heavily on some AJAX to make bits and pieces work. The problem is that they require copying and pasting JavaScript files to the project you want to use it in.
As this JavaScript file only needs to be used once (all instances of the rendered control use the same file) I'd like to do something like add the script element to the headers collection of the page it's used on via a web-resource (embedding the file as a resource in the assembly). In Web-forms this wasn't a problem - you could add a script block to the headers with a specific ID and simply check for it on page load.
What's the MVC equivalent - is there an equivalent?
I'd like a solution that doesn't require the consumer to copy and paste/ add lines to pages or config...any thoughts?
Stephen Walther has some very good articles on MVC, including Html Helpers.
http://weblogs.asp.net/stephenwalther.
A great place to see Html Helpler code is the MVC source code available at
Codeplex.
There is a tutorial at www.asp.net/mvc on Html Helpers
Here ya go, this guy wrote a custom FormlessScriptManager that will let you register scripts even when there is no <form runat="server"> in your page.
http://developmentalmadness.blogspot.com/2008/04/abstracting-systemwebuiscriptmanager.html