Razor MVC poblando una matriz de JavaScript con una matriz de modelo

100

Estoy tratando de cargar una matriz de JavaScript con una matriz de mi modelo. Me parece que esto debería ser posible.

Ninguna de las siguientes formas funciona.

No se puede crear un bucle JavaScript e incrementarlo a través de Model Array con variable JavaScript

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

No se puede crear un bucle de Razor, JavaScript está fuera de alcance

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

Puedo hacer que funcione con

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

Pero no sé por qué debería tener que usar JSON.

Además, mientras que en este momento estoy restringiendo esto a 255 bytes. En el futuro, podría ocupar muchos MB.

Tom Martin
fuente
1
puede acceder a razor en js pero no al revés
Ehsan Sajjad

Respuestas:

215

Esto es posible, solo necesita recorrer la colección de afeitadoras

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Espero que esto ayude

heymega
fuente
Excepto que tuve que declarar mi matriz usando la siguiente notación var myArray = new Array ();
Tom Martin
Gald funciona: sí, de lo contrario, buscará un objeto C # llamado myArray.
heymega
1
Gran ayuda. Pensé que tendría grandes problemas al construir un objeto javascript a partir de un diccionario modelo.
IAbstract
¡Gracias! Necesitaba esto, porque tuve que pasar una lista de cadenas a Javascript y luego a Typecript para mi aplicación angular :)
Bluesight
@mmcrae, @dse declara dentro del bucle foreach. Observe que la d tiene el término VAR al frente. Eso permite que se use dentro del bucle foreach
JhWebDev
8

La sintaxis JSON es prácticamente la sintaxis de JavaScript para codificar su objeto . Por lo tanto, en términos de concisión y rapidez, su propia respuesta es la mejor opción.

Utilizo este enfoque al completar listas desplegables en mi modelo KnockoutJS . P.ej

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>

Tenga en cuenta que estoy usando el paquete Json.NET NuGet para la serialización y ViewBag para pasar datos.

Donal Lafferty
fuente
7

Estaba trabajando con una lista de brindis (mensajes de alerta), List<Alert>de C # y la necesitaba como matriz de JavaScript para Toastr en una vista parcial ( .cshtmlarchivo). El código JavaScript a continuación es lo que funcionó para mí:

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);
});
Soma Mbadiwe
fuente
4

Estaba integrando un control deslizante y necesitaba obtener todos los archivos en la carpeta y estaba teniendo la misma situación de la matriz C # a la matriz javascript. Esta solución de @heymega funcionó perfectamente, excepto que mi analizador de JavaScript estaba molesto por el varuso en foreachbucle. Así que hice un pequeño trabajo para evitar el bucle.

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

Y el código javascript es

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

Espero eso ayude

Ali Umair
fuente
4

Para expandir la respuesta más votada, como referencia, si desea agregar elementos más complejos a la matriz:

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

etc.

Además, si desea pasar la matriz como un parámetro a su controlador, puede secuenciarlo primero:

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

Mcfroob
fuente
Hay un problema con tu código. Debería ser @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Asad
1

Este sería un mejor enfoque que he implementado :)

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

Espero que esto te ayude a evitar que iteres el modelo (codificación feliz)

Muhammad Essa
fuente
0

Si es una matriz simétrica (rectangular), intente insertar una matriz javascript de una sola dimensión; use una navaja para determinar la estructura de la matriz; y luego transformar en una matriz bidimensional.

// 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);
}
John Arundell
fuente