web-dev-qa-db-fra.com

Comment définir des variables javascript à l'aide de MVC4 avec Razor

Quelqu'un peut-il formater le code ci-dessous afin que je puisse définir des variables srcript avec du code c # en utilisant rasoir?

Le système ci-dessous ne fonctionne pas. Je le trouve facile à aider.

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
    @{

     <text>  

    var nonID =@nonProID;
    var proID= @proID;
    window.nonID = @nonProID;
    window.proID=@proID;

    </text>
}
</script>

Je reçois une erreur de conception

enter image description here

Vous devriez jeter un coup d'œil à la sortie de votre page de rasoir. En fait, vous devez savoir ce qui est exécuté par server-side et client-side. Essaye ça:

@{
    int proID = 123; 
    int nonProID = 456;
}

<script>

    var nonID = @nonProID;
    var proID = @proID;
    window.nonID = @nonProID;
    window.proID = @proID;

</script>

La sortie devrait être comme ceci:

enter image description here

Selon la version de Visual Studio que vous utilisez, il indique certains points forts du moment de la conception pour les vues avec rasoir.

38
Felipe Oriani

Voici comment j'ai résolu le problème:

@{int proID = 123; int nonProID = 456;}

<script type="text/javascript">
var nonID = Number(@nonProID);
var proID = Number(@proID);
</script>

Il est auto-documenté et n'implique pas de conversion vers et à partir de texte.


Remarque: veillez à utiliser la fonction Number() pour ne pas créer d'objets new Number(). En effet, l'opérateur exactement égal peut se comporter de manière non évidente:

var y = new Number(123); // Note incorrect usage of "new"
var x = new Number(123);
alert(y === 123); // displays false
alert(x == y); // displays false
18
Scott Gartner

Étant donné que les erreurs de syntaxe de rasoir peuvent devenir problématiques lorsque vous travaillez sur la vue, je comprends parfaitement pourquoi vous souhaitez les éviter. Voici quelques autres options.

<script type="text/javascript">
    // @Model.Count is an int
    var count = '@Model.Count';
    var countInt = parseInt('@Model.ActiveLocsCount');
</script>

Les citations agissent comme des délimiteurs, donc l'analyseur de rasoir est heureux. Mais bien sûr, votre int # C devient une chaîne JS dans la première instruction. Pour les puristes, la deuxième option pourrait être meilleure.

Si quelqu'un a un meilleur moyen de le faire sans les erreurs de syntaxe de rasoir, en particulier en maintenant le type du var, j'aimerais le voir!

15
Sean

J'ai vu plusieurs approches pour contourner le bogue et j'ai fait quelques tests de synchronisation pour voir ce qui fonctionne pour la vitesse ( http://jsfiddle.net/5dwwy/ )

Approches:

  1. Affectation directe

    Dans cette approche, la syntaxe de rasoir est directement affectée à la variable. C'est ce qui jette l'erreur. En tant que référence, le test de vitesse JavaScript effectue simplement une affectation directe d'un nombre à une variable.

  2. Passer par le constructeur `Number`

    Dans cette approche, nous intégrons la syntaxe du rasoir dans un appel au constructeur `Number`, comme dans` Number (@ ViewBag.Value) `.

  3. ParseInt

    Dans cette approche, la syntaxe de rasoir est placée entre guillemets et transmise à la fonction `parseInt`.

  4. Fonction de retour de valeur

    Dans cette approche, une fonction est créée qui prend simplement la syntaxe du rasoir en tant que paramètre et la renvoie.

  5. Fonction de vérification de type

    Dans cette approche, la fonction effectue une vérification de type de base (en recherchant null, en principe) et renvoie la valeur si elle n'est pas nulle.

Procédure:

En utilisant chaque approche mentionnée ci-dessus, un for-loop répète chaque appel de fonction 10 millions de fois, en obtenant le temps total pour la boucle entière. Ensuite, cette boucle for est répétée 30 fois pour obtenir un temps moyen par 10 millions d'actions. Ces temps ont ensuite été comparés les uns aux autres pour déterminer les actions les plus rapides.

Notez que, dans la mesure où JavaScript est en cours d'exécution, les chiffres réels que les autres personnes reçoivent diffèrent, mais l'importance ne réside pas dans le nombre réel, mais dans quelle mesure les chiffres se comparent aux autres.

Résultats:

En utilisant l’approche d’assignation directe, le temps moyen nécessaire pour traiter 10 millions d’affectations était de 98,033 ms. L’utilisation du constructeur Number a donné 1554,93 ms par 10M. De même, la méthode parseInt a pris 1404.27ms. Les deux appels de fonction ont pris 97,5 ms pour la fonction simple et 101,4 ms pour la fonction plus complexe.

Conclusions:

Le code le plus propre à comprendre est l'affectation directe. Cependant, à cause du bogue dans Visual Studio, ceci signale une erreur, ce qui pourrait causer des problèmes avec Intellisense et donner une vague impression de mal se produire. 

Le code le plus rapide était le simple appel de fonction, mais seulement par une faible marge. Comme je n’ai pas fait d’analyse plus poussée, je ne sais pas si cette différence a une signification statistique. La fonction de vérification de type était également très rapide, à peine plus lente qu'une affectation directe et incluait la possibilité que la variable soit nulle. Ce n'est pas vraiment pratique, cependant, car même la fonction de base retournera indéfini si le paramètre est indéfini (null dans la syntaxe razor).

L'analyse de la valeur de rasoir en tant qu'int et son exécution dans le constructeur étaient extrêmement lents, de l'ordre de 15 fois plus lente qu'une affectation directe. Il est fort probable que le constructeur Number appelle parseInt de manière interne, ce qui expliquerait pourquoi cela prend plus de temps qu'une simple parseInt. Cependant, ils ont l'avantage d'être plus significatifs, sans qu'il soit nécessaire d'exécuter une fonction définie en externe (c'est-à-dire ailleurs dans le fichier ou l'application), le constructeur Number minimisant en fait la conversion visible d'un entier en chaîne.

En bout de ligne, ces chiffres ont été générés sur 10 millions d’itérations. Sur un seul article, la vitesse est incroyablement petite. Pour la plupart d'entre eux, le faire simplement passer par le constructeur Number pourrait être le code le plus lisible, bien qu'il soit le plus lent. 

9
saluce
@{
int proID = 123; 
int nonProID = 456;
}

<script>

var nonID = '@nonProID';
var proID = '@proID';
window.nonID = '@nonProID';
window.proID = '@proID';

</script>
5
Ahmed Ghazey

Cela fonctionne si vous faites quelque chose comme ça:

var proID = @proID + 0;

Ce qui produit du code qui ressemble à quelque chose comme:

var proID = 4 + 0;

Un peu bizarre, certes, mais plus de fausses erreurs de syntaxe au moins… .. Malheureusement, les erreurs sont toujours signalées dans VS2013, donc cela n’a pas encore été traité correctement.

2
mabian69

Ce n’était pas tant une réponse qu’un récit édifiant: c’était moi aussi un problème. Je pensais avoir une solution en pré-attendant un zéro et en utilisant la syntaxe @(...). c'est-à-dire que votre code aurait été:

var nonID = 0@(nonProID);
var proID = 0@(proID);

Obtenir une sortie comme:

var nonId = 0123;

Ce que je n'avais pas compris, c'est que c'est ainsi que JavaScript (version 3) représente les nombres octal/base-8 et modifie réellement la valeur. De plus, si vous utilisez la commande "use strict";, votre code sera entièrement cassé, car les nombres octaux ont été supprimés.

Je cherche toujours une solution appropriée à cela.

2
Rob Church

J'ai trouvé une solution très propre qui permet une logique et une interface graphique séparées:

dans votre page rasoir .cshtml, essayez ceci:

<body id="myId" data-my-variable="myValue">

...your page code here

</body>

dans votre fichier .js ou .ts (si vous utilisez TypeScript) pour lire les valeurs stockées à partir de votre vue, mettez-en comme ceci (la bibliothèque jquery est requise):

$("#myId").data("my-variable")
2
Rafael Rivarola

J'ai étudié cette approche:

function getServerObject(serverObject) {
  if (typeof serverObject === "undefined") {
    return null;
  }
  return serverObject;
}

var itCameFromDotNet = getServerObject(@dotNetObject);

Pour moi, cela semble rendre plus sûr du côté JS ... Dans le pire des cas, vous vous retrouvez avec une variable null.

2
Ryan Young

Un des moyens faciles est:

<input type="hidden" id="SaleDateValue" value="@ViewBag.SaleDate" />
<input type="hidden" id="VoidItem" value="@Model.SecurityControl["VoidItem"].ToString()" />

Et puis obtenez la valeur en javascript:

var SaleDate = document.getElementById('SaleDateValue').value;
var Item = document.getElementById('VoidItem').value;
1
Arsman Ahmad

J'utilise une function très simple pour résoudre les erreurs de syntaxe dans le corps des codes JavaScript mélangés avec les codes Razor;)

function n(num){return num;}

var nonID = n(@nonProID);
var proID= n(@proID);
0
RAM

Cela devrait couvrir tous les types principaux:

public class ViewBagUtils
{
    public static string ToJavascriptValue(dynamic val)
    {
        if (val == null) return "null";
        if (val is string) return val;
        if (val is bool) return val.ToString().ToLower();
        if (val is DateTime) return val.ToString();
        if (double.TryParse(val.ToString(), out double dval)) return dval.ToString();

        throw new ArgumentException("Could not convert value.");
    }
}

Et dans votre fichier .cshtml à l'intérieur de la balise <script>:

@using Namespace_Of_ViewBagUtils
const someValue = @ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue);

Notez que pour les valeurs de chaîne, vous devrez utiliser l'expression @ViewBagUtils entre guillemets simples (ou doubles), comme suit:

const someValue = "@ViewBagUtils.ToJavascriptValue(ViewBag.SomeValue)";
0
wm1sr