web-dev-qa-db-fra.com

Accéder à la propriété de modèle de MVC à partir de Javascript

J'ai le modèle suivant qui est enveloppé dans mon modèle de vue

public class FloorPlanSettingsModel
{
    public int Id { get; set; }
    public int? MainFloorPlanId { get; set; }
    public string ImageDirectory { get; set; }
    public string ThumbnailDirectory { get; set; }
    public string IconsDirectory { get; set; }
}

Comment accéder à l'une des propriétés ci-dessus à partir de Javascript?

J'ai essayé cela, mais je me suis "indéfini"

var floorplanSettings = "@Model.FloorPlanSettings";
alert(floorplanSettings.IconsDirectory);
130
Null Reference

Vous pouvez transformer l’ensemble de votre modèle côté serveur en un objet Javascript en procédant comme suit:

var model = @Html.Raw(Json.Encode(Model));

Dans votre cas, si vous voulez juste l'objet FloorPlanSettings, passez simplement la méthode Encode de cette propriété:

var floorplanSettings = @Html.Raw(Json.Encode(Model.FloorPlanSettings));
207

Contenu de la réponse

1) Comment accéder aux données du modèle dans le bloc de code Javascript/Jquery dans le fichier .cshtml

2) Comment accéder aux données du modèle dans le bloc de code Javascript/Jquery dans le fichier .js

Comment accéder aux données de modèle dans le bloc de code Javascript/Jquery dans le fichier .cshtml

Il existe deux types d'affectation de variable c # (Model) à une variable JavaScript.

  1. Affectation de propriété - Types de données de base tels que int, string, DateTime (ex: Model.Name)
  2. Affectation d'objets - Classes personnalisées ou intégrées (ex: Model, Model.UserSettingsObj)

Permet de regarder dans les détails de ces deux missions.

Pour le reste de la réponse, considérons le modèle AppUser ci-dessous comme exemple.

public class AppUser
{
    public string Name { get; set; }
    public bool IsAuthenticated { get; set; }
    public DateTime LoginDateTime { get; set; }
    public int Age { get; set; }
    public string UserIconHTML { get; set; }
}

Et les valeurs que nous attribuons à ce modèle sont

AppUser appUser = new AppUser
{
    Name = "Raj",
    IsAuthenticated = true,
    LoginDateTime = DateTime.Now,
    Age = 26,
    UserIconHTML = "<i class='fa fa-users'></i>"
};

Cession de propriété

Permet d'utiliser une syntaxe différente pour l'affectation et d'observer les résultats.

1) Sans envelopper l'attribution de propriété entre guillemets.

var Name = @Model.Name;  
var Age = @Model.Age;
var LoginTime = @Model.LoginDateTime; 
var IsAuthenticated = @Model.IsAuthenticated;   
var IconHtml = @Model.UserIconHTML;  

enter image description here

Comme vous pouvez le voir, il y a quelques erreurs, Raj et True sont considérés comme des variables javascript et, comme elles n'existent pas, il s'agit d'une erreur variable undefined. Là où, comme pour la variable dateTime, l'erreur est unexpected number, les chiffres ne peuvent pas avoir de caractères spéciaux. Les balises HTML sont converties en noms d'entités afin que le navigateur ne confonde pas vos valeurs et le balisage HTML.

2) Affectation de la propriété à des guillemets.

var Name = '@Model.Name';
var Age = '@Model.Age';
var LoginTime = '@Model.LoginDateTime';
var IsAuthenticated = '@Model.IsAuthenticated';
var IconHtml = '@Model.UserIconHTML'; 

enter image description here

Les résultats sont valides. Envelopper la cession de propriété entre guillemets nous donne une syntaxe valide. Mais notez que le nombre Age est maintenant une chaîne. Donc, si vous ne voulez pas que nous puissions simplement supprimer les guillemets, ils seront rendus sous forme de nombre.

3) Utiliser @Html.Raw mais sans le mettre entre guillemets

 var Name = @Html.Raw(Model.Name);
 var Age = @Html.Raw(Model.Age);
 var LoginTime = @Html.Raw(Model.LoginDateTime);
 var IsAuthenticated = @Html.Raw(Model.IsAuthenticated);
 var IconHtml = @Html.Raw(Model.UserIconHTML);

enter image description here

Les résultats sont similaires à notre scénario de test 1. Cependant, l'utilisation de @Html.Raw() sur la chaîne HTML nous a montré des changements. Le code HTML est conservé sans changer pour ses noms d'entité.

À partir de la documentation Html.Raw ()

Encapsule le balisage HTML dans une instance HtmlString afin qu'elle soit interprétée comme un balisage HTML.

Mais nous avons encore des erreurs dans les autres lignes.

4) Utiliser @Html.Raw et l'envelopper entre guillemets

var Name ='@Html.Raw(Model.Name)';
var Age = '@Html.Raw(Model.Age)';
var LoginTime = '@Html.Raw(Model.LoginDateTime)';
var IsAuthenticated = '@Html.Raw(Model.IsAuthenticated)';
var IconHtml = '@Html.Raw(Model.UserIconHTML)';

enter image description here

Les résultats sont bons avec tous les types. Mais nos données HTML sont maintenant cassées et cela va casser les scripts. Le problème vient du fait que nous utilisons des guillemets simples ' pour envelopper les données et même les données ont des guillemets simples.

Nous pouvons surmonter ce problème avec 2 approches.

1) utilisez les guillemets doubles " " pour envelopper la partie HTML. Comme les données internes n'ont que des guillemets simples. (Assurez-vous qu'après le sautage entre guillemets, il n'y a pas non plus de " dans les données)

  var IconHtml = "@Html.Raw(Model.UserIconHTML)";

2) Echapez la signification des caractères dans votre code côté serveur. Comme

  UserIconHTML = "<i class=\"fa fa-users\"></i>"

Conclusion de l'affectation de propriété

  • Utilisez des guillemets pour dataType non numérique.
  • N'utilisez pas de guillemets pour dataType numérique.
  • Utilisez Html.Raw pour interpréter vos données HTML telles quelles.
  • Prenez soin de vos données HTML pour échapper à la signification des guillemets côté serveur ou utilisez une citation différente de celle utilisée pour les données lors de l'affectation à une variable javascript.

Affectation d'objets

Permet d'utiliser une syntaxe différente pour l'affectation et d'observer les résultats.

1) Sans envelopper l'attribution d'objet entre guillemets.

  var userObj = @Model; 

enter image description here

Lorsque vous affectez un objet c # à une variable javascript, la valeur de la .ToString() de cet objet est attribuée. D'où le résultat ci-dessus.

2 Emballage d'assignation d'objets entre guillemets

var userObj = '@Model'; 

enter image description here

3) Utilisation de Html.Raw sans guillemets.

   var userObj = @Html.Raw(Model); 

enter image description here

4) Utiliser Html.Raw avec des guillemets

   var userObj = '@Html.Raw(Model)'; 

enter image description here

Le Html.Raw ne nous a guère été utile lors de l'attribution d'un objet à une variable.

5) Utilisation de Json.Encode() sans guillemets

var userObj = @Json.Encode(Model); 

//result is like
var userObj = {&quot;Name&quot;:&quot;Raj&quot;,
               &quot;IsAuthenticated&quot;:true,
               &quot;LoginDateTime&quot;:&quot;\/Date(1482572875150)\/&quot;,
               &quot;Age&quot;:26,
               &quot;UserIconHTML&quot;:&quot;\u003ci class=\&quot;fa fa-users\&quot;\u003e\u003c/i\u003e&quot;
              };

Nous constatons certains changements. Nous constatons que notre modèle est interprété comme un objet. Mais nous avons changé ces caractères spéciaux en entity names. En outre, le fait de mettre la syntaxe ci-dessus entre guillemets n’est pas très utile. Nous obtenons simplement le même résultat entre guillemets.

À partir de la documentation de Json.Encode ()

Convertit un objet de données en une chaîne au format JSON (JavaScript Object Notation).

Comme vous avez déjà rencontré ce problème de entity Name avec l'attribution de propriété et si vous vous en souvenez bien, nous l'avons surmonté avec l'utilisation de Html.Raw. Alors essayons ça. Permet de combiner Html.Raw et Json.Encode

6) Utiliser Html.Raw et Json.Encode sans guillemets.

var userObj = @Html.Raw(Json.Encode(Model));

Le résultat est un objet Javascript valide

 var userObj = {"Name":"Raj",
     "IsAuthenticated":true,
     "LoginDateTime":"\/Date(1482573224421)\/",
     "Age":26,
     "UserIconHTML":"\u003ci class=\"fa fa-users\"\u003e\u003c/i\u003e"
 };

enter image description here

7) Utiliser Html.Raw et Json.Encode entre guillemets.

var userObj = '@Html.Raw(Json.Encode(Model))';

enter image description here

Comme vous pouvez le voir, les guillemets nous donnent une donnée JSON

Conslusion lors de l'attribution d'objet

  • Utilisez Html.Raw et Json.Encode dans combintaion pour affecter votre objet à une variable javascript en tant qu'objet JavaScript .
  • Utilisez Html.Raw et Json.Encode enroulez-le également dans quotes pour obtenir un JSON

Remarque: Si vous avez observé que le format de données DataTime n'est pas correct. En effet, comme indiqué précédemment, Converts a data object to a string that is in the JavaScript Object Notation (JSON) format et JSON ne contiennent pas de type date. D'autres options pour résoudre ce problème consistent à ajouter une autre ligne de code pour gérer ce type uniquement à l'aide de l'objet javascipt Date ()

var userObj.LoginDateTime = new Date('@Html.Raw(Model.LoginDateTime)'); 
//without Json.Encode


Comment accéder aux données du modèle dans le bloc de code Javascript/Jquery dans le fichier .js

La syntaxe Razor n'a aucune signification dans le fichier .js et par conséquent, nous ne pouvons pas utiliser directement notre modèle sans un fichier .js. Cependant, il existe une solution de contournement.

1) La solution utilise des variables globales javascript .

Nous devons affecter la valeur à une variable globale javascipt et ensuite utiliser cette variable dans tous les blocs de code de vos fichiers .cshtml et .js. Donc, la syntaxe serait

<script type="text/javascript">
  var userObj = @Html.Raw(Json.Encode(Model)); //For javascript object
  var userJsonObj = '@Html.Raw(Json.Encode(Model))'; //For json data
</script>

Avec ceci en place, nous pouvons utiliser les variables userObj et userJsonObj selon les besoins.

Remarque: Personnellement, je ne suggère pas d'utiliser des variables globales car cela devient très difficile pour la maintenance. Cependant, si vous n'avez pas d'autre option, vous pouvez l'utiliser avec une convention de nommage appropriée .. quelque chose comme userAppDetails_global.

2) Utilisation de function () ou closure Wrap all le code qui dépend des données de modèle dans une fonction. Puis exécutez cette fonction à partir du fichier .cshtml.

external.js

 function userDataDependent(userObj){
  //.... related code
 }

Fichier .cshtml

 <script type="text/javascript">
  userDataDependent(@Html.Raw(Json.Encode(Model))); //execute the function     
</script>

Remarque: Votre fichier externe doit être référencé avant le script ci-dessus. Sinon, la fonction userDataDependent n'est pas définie.

Notez également que la fonction doit également avoir une portée globale. Donc, quelle que soit la solution, nous devons faire face à des acteurs globaux.

104
Rajshekar Reddy

essayez ceci: (vous avez manqué les guillemets simples)

var floorplanSettings = '@Html.Raw(Json.Encode(Model.FloorPlanSettings))';
18
tennisBoy

Envelopper la propriété modèle autour de parens a fonctionné pour moi. Vous rencontrez toujours le même problème lorsque Visual Studio se plaint du point-virgule, mais cela fonctionne.

var closedStatusId = @(Model.ClosedStatusId);
3
FROgistics

Si "ReferenceError: le modèle n'est pas défini" = une erreur est générée, vous pouvez essayer d'utiliser la méthode suivante:

$(document).ready(function () {

    @{  var serializer = new System.Web.Script.Serialization.JavaScriptSerializer();
         var json = serializer.Serialize(Model);
    }

    var model = @Html.Raw(json);
    if(model != null && @Html.Raw(json) != "undefined")
    {
        var id= model.Id;
        var mainFloorPlanId = model.MainFloorPlanId ;
        var imageDirectory = model.ImageDirectory ;
        var iconsDirectory = model.IconsDirectory ;
    }
});

J'espère que cela t'aides...

0
Murat Yıldız