Razor MVC remplissant un tableau Javascript avec un tableau de modèles


100

J'essaye de charger un tableau JavaScript avec un tableau de mon modèle. Il me semble que cela devrait être possible.

Aucune des méthodes ci-dessous ne fonctionne.

Impossible de créer une boucle JavaScript et d'incrémenter via Model Array avec une variable JavaScript

for(var j=0; j<255; j++)
{
    jsArray = (@(Model.data[j])));
}

Impossible de créer une boucle Razor, JavaScript est hors de portée

@foreach(var d in Model.data)
{
    jsArray = d;
}

Je peux le faire fonctionner avec

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

Mais je ne sais pas pourquoi je devrais utiliser JSON.

Aussi, en ce moment, je limite cela à 255 octets. À l'avenir, il pourrait atteindre de nombreux Mo.


1
vous pouvez accéder au rasoir dans js mais pas l'inverse
Ehsan Sajjad

Réponses:


216

C'est possible, il vous suffit de parcourir la collection de rasoirs

<script type="text/javascript">

    var myArray = [];

    @foreach (var d in Model.data)
    {
        @:myArray.push("@d");
    }

    alert(myArray);

</script>

J'espère que cela t'aides


Sauf que j'ai dû déclarer mon tableau en utilisant la notation suivante var myArray = new Array ();
Tom Martin

Gald ça marche - Oui sinon il recherchera un objet C # appelé myArray.
heymega

1
Une grande aide. Je pensais avoir d'énormes problèmes avec la construction d'un objet javascript à partir d'un dictionnaire de modèles.
IAbstract

Je vous remercie! J'avais besoin de cela, car je devais passer une liste de chaînes à Javascript puis à Typescript pour mon application angulaire :)
Bluesight

@mmcrae, @dest déclaré dans la boucle foreach. Notez que le d a le terme VAR devant. Cela lui permet d'être utilisé dans la boucle foreach
JhWebDev

8

La syntaxe JSON est à peu près la syntaxe JavaScript pour coder votre objet . Par conséquent, en termes de concision et de rapidité, votre propre réponse est le meilleur pari.

J'utilise cette approche lors du remplissage de listes déroulantes dans mon modèle KnockoutJS . Par exemple

var desktopGrpViewModel = {
    availableComputeOfferings: ko.observableArray(@Html.Raw(JsonConvert.SerializeObject(ViewBag.ComputeOfferings))),
    desktopGrpComputeOfferingSelected: ko.observable(),
};
ko.applyBindings(desktopGrpViewModel);

...

<select name="ComputeOffering" class="form-control valid" id="ComputeOffering" data-val="true" 
data-bind="options: availableComputeOffering,
           optionsText: 'Name',
           optionsValue: 'Id',
           value: desktopGrpComputeOfferingSelect,
           optionsCaption: 'Choose...'">
</select>

Notez que j'utilise le package NuGet Json.NET pour la sérialisation et le ViewBag pour transmettre des données.


7

Je travaillais avec une liste de toasts (messages d'alerte), à List<Alert>partir de C # et j'en avais besoin comme tableau JavaScript pour Toastr dans une vue partielle ( .cshtmlfichier). Le code JavaScript ci-dessous est ce qui a fonctionné pour moi:

var toasts = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(alerts));
toasts.forEach(function (entry) {
    var command = entry.AlertStyle;
    var message = entry.Message;
    if (command === "danger") { command = "error"; }
    toastr[command](message);
});

4

J'intégrais un curseur et j'avais besoin d'obtenir tous les fichiers dans le dossier et j'avais la même situation de tableau C # au tableau javascript. Cette solution de @heymega fonctionnait parfaitement sauf que mon analyseur javascript était ennuyé lors de l' varutilisation en foreachboucle. J'ai donc fait un petit travail pour éviter la boucle.

var allowedExtensions = new string[] { ".jpg", ".jpeg", ".bmp", ".png", ".gif" };

var bannerImages = string.Join(",", Directory.GetFiles(Path.Combine(System.Web.Hosting.HostingEnvironment.ApplicationPhysicalPath, "Images", "banners"), "*.*", SearchOption.TopDirectoryOnly)
    .Where(d => allowedExtensions.Contains(Path.GetExtension(d).ToLower()))
    .Select(d => string.Format("'{0}'", Path.GetFileName(d)))
    .ToArray());

Et le code javascript est

var imagesArray = new Array(@Html.Raw(bannerImages));

J'espère que ça aide


4

Pour développer la réponse la plus votée, à titre de référence, si vous souhaitez ajouter des éléments plus complexes au tableau:

@:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");

etc.

De plus, si vous souhaitez passer le tableau en tant que paramètre à votre contrôleur, vous pouvez d'abord le stringifier:

myArray = JSON.stringify({ 'myArray': myArray });


Il y a un problème avec votre code. Ça devrait être @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Asad

1

Ce serait une meilleure approche que j'ai mise en œuvre :)

@model ObjectUser
@using System.Web.Script.Serialization
@{ 
    var javaScriptSearilizer = new JavaScriptSerializer();
    var searializedObject = javaScriptSearilizer.Serialize(Model);
 }

<script>
    var searializedObject = @Html.Raw(searializedObject )
    console.log(searializedObject);
    alert(searializedObject);
</script>

J'espère que cela vous aidera à vous empêcher d'itérer le modèle (bon codage)


0

S'il s'agit d'un tableau symétrique (rectangulaire), essayez de pousser dans un tableau javascript à une seule dimension; utilisez un rasoir pour déterminer la structure du tableau; puis transformez en un tableau à 2 dimensions.

// this just sticks them all in a one dimension array of rows * cols
var myArray = new Array();
@foreach (var d in Model.ResultArray)
{
    @:myArray.push("@d");
}

var MyA = new Array();

var rows = @Model.ResultArray.GetLength(0);
var cols = @Model.ResultArray.GetLength(1);

// now convert the single dimension array to 2 dimensions
var NewRow;
var myArrayPointer = 0;

for (rr = 0; rr < rows; rr++)
{
  NewRow = new Array();
  for ( cc = 0; cc < cols; cc++)
  {
    NewRow.push(myArray[myArrayPointer]);
    myArrayPointer++;
  }
  MyA.push(NewRow);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.