asp.net-mvc: razor '@' symbol in js file

57,792

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.

Share:
57,792
gdoron is supporting Monica
Author by

gdoron is supporting Monica

Doron Grinzaig

Updated on July 08, 2022

Comments

  • gdoron is supporting Monica
    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
    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
    gdoron is supporting Monica over 12 years
    Thanks, the second approach isn't a bad coupling between the view and the js file? Do you have a better way?
  • Aliostad
    Aliostad over 12 years
    Both are coupling. There is no way to uncouple unless you write a view engine to process js files before rendering. See my updates.
  • BigMike
    BigMike over 12 years
    what 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
    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
    BigMike over 12 years
    thanks 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
    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
    gdoron is supporting Monica over 12 years
    what about this way that I suggested? stackoverflow.com/questions/7902213/…
  • gdoron is supporting Monica
    gdoron is supporting Monica over 12 years
    Nice! 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
    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
    Aliostad over 12 years
    Sounds OK. My +1. Either partial or full view, does not change anything. It is all coupling view with js.
  • gdoron is supporting Monica
    gdoron is supporting Monica over 12 years
    I think I've found the solution for it : stackoverflow.com/questions/7902213/… what do you think?
  • A Coder
    A Coder over 9 years
  • Memet Olsen
    Memet Olsen about 8 years
    First link is broken
  • gdoron is supporting Monica
    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
    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
    QMaster over 5 years
    Thanks. 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
    Drunken Code Monkey about 3 years
    This will not work, the partial view will be rendered and the JS will be in the main HTML at the end...