Razor MVC Wypełnianie tablicy JavaScript za pomocą tablicy modelu

100

Próbuję załadować tablicę JavaScript z tablicą z mojego modelu. Wydaje mi się, że powinno to być możliwe.

Żaden z poniższych sposobów nie działa.

Nie można utworzyć pętli JavaScript i inkrementować za pomocą tablicy modelu ze zmienną JavaScript

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

Nie można utworzyć pętli Razor, JavaScript jest poza zakresem

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

Mogę to wykorzystać

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

Ale nie wiem, dlaczego powinienem używać JSON.

Również w tej chwili ograniczam to do 255 bajtów. W przyszłości może mieć wiele MB.

Tom Martin
źródło
1
możesz uzyskać dostęp do maszynki do golenia w js, ale nie odwrotnie
Ehsan Sajjad

Odpowiedzi:

216

Jest to możliwe, wystarczy przejrzeć kolekcję maszynek do golenia

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Mam nadzieję że to pomoże

heymega
źródło
Z wyjątkiem tego, że musiałem zadeklarować moją tablicę przy użyciu następującej notacji var myArray = new Array ();
Tom Martin
Gald to działa - tak, w przeciwnym razie będzie szukać obiektu C # o nazwie myArray.
heymega
1
Wielka pomoc. Pomyślałem, że będę miał ogromne problemy z budowaniem obiektu javascript ze słownika modelu.
IAbstract
Dziękuję Ci! Potrzebowałem tego, ponieważ musiałem przekazać listę ciągów do Javascript, a następnie do maszynopisu dla mojej aplikacji Angular :)
Bluesight
@mmcrae, @djest zadeklarowana wewnątrz pętli foreach. Zauważ, że d ma na początku termin VAR. Dzięki temu można go używać w pętli foreach
JhWebDev
8

Składnia JSON jest w zasadzie składnią JavaScript do kodowania obiektu . Dlatego pod względem zwięzłości i szybkości najlepszą odpowiedzią jest twoja własna odpowiedź.

Używam tego podejścia podczas wypełniania list rozwijanych w moim modelu KnockoutJS . Na przykład

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>

Należy pamiętać, że używam pakietu NuGet Json.NET do serializacji i ViewBag do przekazywania danych.

Donal Lafferty
źródło
7

Pracowałem z listą toastów (komunikatów ostrzegawczych) List<Alert>z C # i potrzebowałem jej jako tablicy JavaScript dla Toastra w częściowym widoku ( .cshtmlplik). Poniższy kod JavaScript zadziałał dla mnie:

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
źródło
4

Integrowałem suwak i musiałem pobrać wszystkie pliki w folderze i miałem taką samą sytuację tablicy C # z tablicą javascript.To rozwiązanie @heymega działało idealnie, z wyjątkiem tego, że mój parser javascript był zirytowany podczas varużywania w foreachpętli. Więc trochę popracowałem nad unikaniem pętli.

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

A kod javascript to

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

Mam nadzieję, że to pomoże

Ali Umair
źródło
4

Aby rozwinąć odpowiedź, która została najwyżej oceniona, w celach informacyjnych, jeśli chcesz dodać bardziej złożone elementy do tablicy:

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

itp.

Ponadto, jeśli chcesz przekazać tablicę jako parametr do swojego kontrolera, możesz najpierw określić ją jako ciąg znaków:

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

mcfroob
źródło
Wystąpił problem z Twoim kodem. Powinno być @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Asad
1

To byłoby lepsze podejście, ponieważ wdrożyłem :)

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

Mam nadzieję, że pomoże ci to zapobiec iteracji modelu (szczęśliwe kodowanie)

Muhammad Essa
źródło
0

Jeśli jest to tablica symetryczna (prostokątna), spróbuj umieścić ją w jednowymiarowej tablicy javascript; użyć maszynki do golenia do określenia struktury macierzy; a następnie przekształcić w dwuwymiarową tablicę.

// 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
źródło