J'ai un .csHtml - fichier de rasoir avec une fonction javascript qui utilise la fonction @Url.Content C # à l'intérieur pour l'URL ajax.
Je souhaite déplacer cette fonction vers un fichier .js référencé depuis ma vue.

Le problème est que javascript ne "connaît" pas le symbole @ et n'analyse pas le code C #.
Existe-t-il un moyen de référencer des fichiers .js à partir de la vue avec le symbole "@"?

88
gdoron is supporting Monica 26 oct. 2011 à 15:54

8 réponses

Meilleure réponse

Vous pouvez utiliser des attributs HTML5 data-*. Supposons que vous souhaitiez effectuer une action lorsqu'un élément DOM tel qu'un div est cliqué. Alors:

<div id="foo" data-url="@Url.Content("~/foobar")">Click me</div>

Puis dans votre fichier javascript séparé, vous pouvez travailler discrètement avec le DOM:

$('#foo').click(function() {
    var url = $(this).data('url');
    // do something with this url
});

De cette façon, vous pourriez avoir une séparation pure entre le balisage et le script sans avoir besoin de balises côté serveur dans vos fichiers javascript.

87
Darin Dimitrov 9 janv. 2012 à 19:32

Ce n'est probablement pas la bonne approche. Considérant la séparation des préoccupations. Vous devriez avoir un data injector dans votre classe JavaScript et qui, dans la plupart des cas, les données sont JSON.

Créez un fichier JS dans votre dossier script et ajoutez cette référence à votre View

<script src="@Url.Content("~/Scripts/yourJsFile.js")" type="text/javascript"></script>

Maintenant, considérez une classe JavaScript littérale dans votre yourJsFile.js:

var contentSetter = {
    allData: {},
    loadData: function (data) {
        contentSetter.allData = eval('(' + data + ')');
    },
    setContentA: function () {
        $("#contentA").html(allData.contentAData);
    },
    setContentB: function () {
        $("#contentB").html(allData.contentAData);
    }
};

Déclarez également une classe

public class ContentData
{
    public string ContentDataA { get; set }
    public string ContentDataB { get; set }
}

Maintenant, à partir de votre Action, procédez comme suit:

public ActionResult Index() {
    var contentData = new ContentData();
    contentData.ContentDataA = "Hello";
    contentData.ContentDataB = "World";
    ViewData.Add("contentData", contentData);
}

Et de votre point de vue:

<div id="contentA"></div>
<div id="contentB"></div>

<script type="text/javascript">
    contentSetter.loadData('@Json.Encode((ContentData) ViewData["contentData"])');
    contentSetter.setContentA();
    contentSetter.setContentB();
</script>
4
Abdul Munim 26 oct. 2011 à 13:00

Pour obtenir la variable @ dans votre fichier .js, vous devrez utiliser une variable globale et définir la valeur de cette variable à partir de la vue mvc qui utilise ce fichier .js.

Fichier JavaScript:

var myValue;

function myFunc() {
  alert(myValue);
}

Fichier de vue MVC:

<script language="text/javascript">
    myValue = @myValueFromModel;
</script>

Assurez-vous simplement que tous les appels à votre fonction se produisent APRÈS que la valeur a été définie par la vue.

7
Joel Etherton 26 oct. 2011 à 12:04

J'ai récemment blogué sur ce sujet: Génération de fichiers JavaScript externes à l'aide de vues partielles de rasoir.

Ma solution consiste à utiliser un attribut personnalisé (ExternalJavaScriptFileAttribute) qui rend une vue partielle de Razor telle quelle, puis la renvoie sans les balises <script> environnantes. Cela en fait un fichier JavaScript externe valide.

4
Marius Schulz 14 févr. 2014 à 15:57

Je pense que vous êtes obligé de mettre ce code JS dans la vue. L'analyseur Razor, pour autant que je sache, ne regardera pas les fichiers .js, donc tout ce que vous avez qui utilise @ ne fonctionnera pas. PLus, comme vous l'avez remarqué, Javascript lui-même n'aime pas ce caractère @ qui traîne sans raison, sinon, disons, dans une chaîne.

1
Jason Evans 26 oct. 2011 à 11:58

Eh bien, je viens de trouver un moteur de rasoir sur nuget qui le fait! La signification résout la syntaxe @!
Son nom est RazorJS .

Le package Nuget


Mise à jour 2016:
Le package n'a pas été mis à jour depuis 5 ans et le lien vers le site du projet est mort. Je ne recommande plus aux gens d'utiliser cette bibliothèque.

19
gdoron is supporting Monica 2 mars 2016 à 13:15

J'habille généralement JS ayant besoin d'accéder aux propriétés du modèle, dans les fonctions, puis je passe le @something dans la vue. Par exemple

<script type="text/javascript">
function MyFunction(somethingPresentInTheView) {
  alert(somethingPresentInTheView);
}
</script>

Dans la vue j'ajoute l'invocation de fonction via (juste un exemple):

<input type='button' onclick="MyFunction('@Model.PropertyNeeded')" />
2
BigMike 26 oct. 2011 à 12:29

Une façon de résoudre le problème est:

Ajout d'une vue partielle avec les fonctions javascript à la vue.
De cette façon, vous pouvez utiliser le symbole @ et toutes vos fonctions javascript sont séparées de la vue.

10
gdoron is supporting Monica 16 déc. 2012 à 16:12
7902213