web-dev-qa-db-fra.com

asp.net-mvc: symbole du rasoir '@' dans le fichier js

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

Le problème est que javascript ne "connait" pas le @ symbole et n'analyse pas le code C #.
Y a-t-il un moyen de faire référence à .js fichiers de la vue avec le symbole "@"?

87
gdoron

Vous pouvez utiliser HTML5 data-* les attributs. Supposons que vous souhaitiez effectuer une action lorsque vous cliquez sur un élément du DOM, tel qu'un div. Alors:

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

et ensuite 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 jamais besoin de balises côté serveur dans vos fichiers javascript.

87
Darin Dimitrov

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

Le package Nuget


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

18
gdoron

One way pour résoudre le problème est:

Ajouter 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

Vous avez deux options:

  • Utilisez la valeur comme paramètre dans la fonction et connectez-vous dans la vue
  • Créez un espace de noms (à la place d'une variable de niveau public, ce qui est considéré comme une mauvaise pratique dans JS) et définissez cette valeur en haut de la page, puis utilisez-la dans votre js.

Par exemple:

 var MyCompany = 
 {
   MyProject: {
                  MyVariable:""
               }
  };

Et ensuite, à votre avis, définissez-le:

MyCompany.MyProject.MyVariable = @....

MISE À JOUR

Vous pourriez vous demander qu’aucun n’est bon en raison du couplage, eh bien, c’est vrai, vous couplez js et view. C’est pourquoi les scripts doivent être inconscients de l’emplacement où ils s’exécutent, c’est donc un symptôme d’une organisation non optimale des fichiers.

Quoi qu'il en soit, il existe une troisième option pour créer un moteur de vue, exécuter les fichiers js sur le rasoir et renvoyer les résultats. C'est plus propre mais beaucoup plus lent, donc pas recommandé non plus.

9
Aliostad

Pour obtenir le @ 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 MVC View:

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

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

7
Joel Etherton

J'ai récemment blogué à propos de 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 restitue une vue partielle de Razor, puis le renvoie sans le <script> Mots clés. Cela en fait un fichier JavaScript externe valide.

4
Marius Schulz

Ce n'est probablement pas la bonne approche. Considérant la séparation des préoccupations. Vous devriez avoir un data injector sur votre classe JavaScript et 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 fichier View.

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

Maintenant, considérons 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);
    }
};

Aussi déclarer une classe

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

Maintenant, à partir de votre Action, faites ceci:

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

J'habite généralement JS ayant besoin d'accéder aux propriétés du modèle, dans des fonctions, puis 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

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. Comme vous l’avez remarqué, javascript n’aime pas cette chose @ caractère traînant sans raison, autre que dans une chaîne.

1
Jason Evans