Razor MVC che popola array Javascript con Model Array


100

Sto cercando di caricare un array JavaScript con un array dal mio modello. Mi sembra che questo dovrebbe essere possibile.

Nessuno dei modi seguenti funziona.

Impossibile creare un loop JavaScript e incrementare tramite Model Array con la variabile JavaScript

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

Impossibile creare un ciclo Razor, JavaScript è fuori ambito

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

Posso farlo funzionare con

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

Ma non so perché dovrei usare JSON.

Anche se al momento sto limitando questo a 255 byte. In futuro potrebbe incorrere in molti MB.


1
puoi accedere a Razor in js ma non viceversa
Ehsan Sajjad

Risposte:


215

Questo è possibile, devi solo scorrere la raccolta del rasoio

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Spero che questo ti aiuti


Tranne che dovevo dichiarare il mio array usando la seguente notazione var myArray = new Array ();
Tom Martin,

Gald funziona - Sì, altrimenti cercherà un oggetto C # chiamato myArray.
heymega

1
Grande aiuto. Ho pensato che avrei avuto dei grossi problemi con la creazione di un oggetto javascript da un dizionario modello.
IAbstract

Grazie! Ne avevo bisogno, perché dovevo passare un elenco di stringhe a Javascript e poi a Typescript per la mia app angolare :)
Bluesight

@mmcrae, @dviene dichiarato all'interno del ciclo foreach. Notare che la d ha il termine VAR davanti. Ciò consente di utilizzarlo all'interno del ciclo foreach
JhWebDev

8

La sintassi JSON è praticamente la sintassi JavaScript per la codifica dell'oggetto . Pertanto, in termini di concisione e velocità, la tua risposta è la soluzione migliore.

Uso questo approccio quando popolo elenchi a discesa nel mio modello KnockoutJS . Per esempio

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>

Tieni presente che sto usando il pacchetto Json.NET NuGet per la serializzazione e ViewBag per passare i dati.


7

Stavo lavorando con un elenco di toast (messaggi di avviso), List<Alert>da C # e ne avevo bisogno come array JavaScript per Toastr in una vista parziale ( .cshtmlfile). Il codice JavaScript di seguito è ciò che ha funzionato per me:

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

Stavo integrando uno slider e avevo bisogno di ottenere tutti i file nella cartella e stavo avendo la stessa situazione dell'array C # nell'array javascript Questa soluzione di @heymega ha funzionato perfettamente tranne che il mio parser javascript era infastidito vardall'uso in foreachloop. Quindi ho fatto un piccolo lavoro evitando il loop.

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());

E il codice javascript è

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

Spero che sia d'aiuto


4

Per espandere la risposta più votata, come riferimento, se si desidera aggiungere elementi più complessi all'array:

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

eccetera.

Inoltre, se vuoi passare l'array come parametro al tuo controller, puoi prima stringerlo:

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


C'è un problema con il tuo codice. Dovrebbe essere @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Assad

1

Questo sarebbe un approccio migliore dato che ho implementato :)

@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>

Spero che questo ti aiuti a impedirti di iterare il modello (codifica felice)


0

Se è un array simmetrico (rettangolare), prova a inserire un array javascript a dimensione singola; usa il rasoio per determinare la struttura dell'array; e poi trasformalo in un array bidimensionale.

// 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);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.