asp.net-mvc: razor '@' symbol in js file
Solution 1
You could use HTML5 data-*
attributes. Let's suppose that you want to perform some action when some DOM element such as a div is clicked. So:
<div id="foo" data-url="@Url.Content("~/foobar")">Click me</div>
and then in your separate javascript file you could work unobtrusively with the DOM:
$('#foo').click(function() {
var url = $(this).data('url');
// do something with this url
});
This way you could have a pure separation between markup and script without you ever needing any server side tags in your javascript files.
Solution 2
Well I've just found a razor engine on nuget that does it! Meaning solves @
syntax!
It's name is RazorJS.
The Nuget package
2016 Update:
The package wasn't updated for 5 years, and the project site link is dead. I do not recommend people to use this library anymore.
Solution 3
One way to tackle the problem is:
Adding a partial view with the javascript functions to the view.
This way you can use the @
symbol and all your javascript
functions are separated from the view.
Solution 4
You have two options:
- Use the value as a parameter in the function and wire-up in the view
- Create a namespace (instead of public level variable which is considered bad practice in JS) and set this value at the top of the page and then use it in your js
For example:
var MyCompany =
{
MyProject: {
MyVariable:""
}
};
And then in your view, set it:
MyCompany.MyProject.MyVariable = @....
UPDATE
You might wonder none is any good because of coupling, well it is true, you are coupling js and view. That is why scripts must be oblivious to the location they are running in so it is a symptom of non-optimum organization of files.
Anyway there is a third option to create a view engine and run the js files against the razor and send the results back. This is cleaner but much slower so not recommended either.
Solution 5
In order to get the @
variable into your .js file you'll have to use a global variable and set the value of that variable from the mvc view that is making use of that .js file.
JavaScript file:
var myValue;
function myFunc() {
alert(myValue);
}
MVC View file:
<script language="text/javascript">
myValue = @myValueFromModel;
</script>
Just be sure that any calls to your function happen AFTER the value has been set by the view.
Comments
-
gdoron is supporting Monica almost 2 years
I have a
.csHtml
-razor file with a javascript function that uses the@Url.Content
C# function inside for the ajax URL.
I want to move that function to a.js
file referenced from my view.The problem is that javascript doesn't "know" the
@
symbol and doesn't parse the the C# code.
Is there a way to reference.js
files from view with "@" symbol? -
Richard Dalton over 12 years+1 I do the first method. Call an initialization function from your view passing in all of the data you require.
-
gdoron is supporting Monica over 12 yearsThanks, the second approach isn't a bad coupling between the view and the js file? Do you have a better way?
-
Aliostad over 12 yearsBoth are coupling. There is no way to uncouple unless you write a view engine to process js files before rendering. See my updates.
-
BigMike over 12 yearswhat about passing directly myValue as a parameter to the function ? I prefer to have explicit calling with param than relying on globals, however I'm not so keen on javascript so I may be missing some important aspect of having a global.
-
Joel Etherton over 12 years@BigMike: Certainly acceptable. The method I put forth above simply makes the variable available to multiple functions simultaneously, but using parameters is just as good.
-
BigMike over 12 yearsthanks for clarification. It would be great to have some sort of js object version of the model automatically (via Attributes in model class will be great), this will just add a pattern and a fully namespace aware variable solution. I guess the big problem would be how to inject the code in the generated html sent to the browser (directly of via <script> tag). I think I'll perform some experiments on this as soon as my current project will be over.
-
Joel Etherton over 12 years@BigMike: This should be fairly easy to accomplish by using the DataContractJsonSerializer class (msdn.microsoft.com/en-us/library/…). It would create a JSON version of your class that could be parsed into the view.
-
gdoron is supporting Monica over 12 yearswhat about this way that I suggested? stackoverflow.com/questions/7902213/…
-
gdoron is supporting Monica over 12 yearsNice! but I think it's too complicated... what do you think about my answer? stackoverflow.com/questions/7902213/…. by the way you have copy paste error in setContentB you wrote contentAData. thank!
-
Abdul Munim over 12 years@gdoron Believe me, managing JS classes and considering separation is a life saver when you have a huge project
-
Aliostad over 12 yearsSounds OK. My +1. Either partial or full view, does not change anything. It is all coupling view with js.
-
gdoron is supporting Monica over 12 yearsI think I've found the solution for it : stackoverflow.com/questions/7902213/… what do you think?
-
A Coder over 9 yearsCan you look into this? stackoverflow.com/questions/27702322/…
-
Memet Olsen about 8 yearsFirst link is broken
-
gdoron is supporting Monica about 8 years@MemetOlsen, indeed, sorry but I can't find a copy of it, so I removed it :(
-
Memet Olsen about 8 years@gdoron, no problem. I just wanted to let you know about the dead link. As you've stated, the package wasn't updated for 5 years so it's probably a bad idea to use it anyway.
-
QMaster over 5 yearsThanks. I think for multiple values can be a headache. Firstly I thought it can to solve my problem but after giving that a try I found so many referrals in my code and decide to find another way.
-
Drunken Code Monkey about 3 yearsThis will not work, the partial view will be rendered and the JS will be in the main HTML at the end...