Razor MVC Preenchendo array Javascript com Model Array

100

Estou tentando carregar um array JavaScript com um array do meu modelo. Parece-me que isso deveria ser possível.

Nenhuma das maneiras abaixo funciona.

Não é possível criar um loop JavaScript e incrementar por meio de matriz de modelo com variável JavaScript

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

Não é possível criar um loop Razor, JavaScript está fora do escopo

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

Eu posso fazer funcionar com

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

Mas não sei por que deveria usar JSON.

Além disso, no momento estou restringindo isso a 255 bytes. No futuro, ele pode rodar em muitos MBs.

Tom Martin
fonte
1
você pode acessar o barbeador em js, mas não vice-versa
Ehsan Sajjad

Respostas:

215

Isso é possível, você só precisa percorrer a coleção de navalhas

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Espero que isto ajude

Heymega
fonte
Exceto que tive que declarar meu array usando a seguinte notação var myArray = new Array ();
Tom Martin de
Gald funciona - Sim, caso contrário, ele procurará um objeto C # chamado myArray.
heymega
1
Grande ajuda. Achei que teria grandes problemas para criar um objeto javascript a partir de um dicionário de modelo.
IAbstract
Obrigado! Eu precisava disso, porque tive que passar uma Lista de Strings para Javascript e, em seguida, para Texto Dactilografado para meu aplicativo Angular :)
Bluesight
@mmcrae, @dé declarado dentro do loop foreach. Observe que o d tem o termo VAR na frente. Isso permite que ele seja usado dentro do loop foreach
JhWebDev
8

A sintaxe JSON é basicamente a sintaxe JavaScript para codificar seu objeto . Portanto, em termos de concisão e rapidez, sua própria resposta é a melhor aposta.

Eu uso essa abordagem ao preencher listas suspensas em meu modelo KnockoutJS . Por exemplo

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>

Observe que estou usando o pacote Json.NET NuGet para serialização e o ViewBag para passar dados.

Donal Lafferty
fonte
7

Estava trabalhando com uma lista de toasts (mensagens de alerta), List<Alert>em C # e precisava dela como array JavaScript para Toastr em uma visão parcial ( .cshtmlarquivo). O código JavaScript abaixo é o que funcionou para mim:

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
fonte
4

Eu estava integrando um controle deslizante e precisava obter todos os arquivos da pasta e estava tendo a mesma situação de array C # para array javascript. Esta solução de @heymega funcionou perfeitamente, exceto que meu analisador de javascript estava incomodado com o varuso em foreachloop. Então, resolvi evitar o 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 o código javascript é

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

Espero que ajude

Ali Umair
fonte
4

Para expandir a resposta mais votada, para referência, se você deseja adicionar itens mais complexos à matriz:

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

etc.

Além disso, se você deseja passar o array como um parâmetro para o seu controlador, você pode restringi-lo primeiro:

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

mcfroob
fonte
Existe um problema com o seu código. Deve ser @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Asad
1

Essa seria a melhor abordagem conforme implementei :)

@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 isso ajude você a evitar a iteração do modelo (feliz programação)

Muhammad Essa
fonte
0

Se for uma matriz simétrica (retangular), tente empurrar para uma matriz javascript de dimensão única; use o razor para determinar a estrutura do array; e então se transformar em uma 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
fonte