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 "@"?
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.
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.
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.
Vous avez deux options:
Par exemple:
var MyCompany =
{
MyProject: {
MyVariable:""
}
};
Et ensuite, à votre avis, définissez-le:
MyCompany.MyProject.MyVariable = @....
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.
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.
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.
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>
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')" />
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.