Razor MVC Заполнение массива Javascript массивом моделей

100

Я пытаюсь загрузить массив JavaScript с массивом из моей модели. Мне кажется, это должно быть возможно.

Ни один из приведенных ниже способов не работает.

Невозможно создать цикл JavaScript и выполнить приращение через массив модели с переменной JavaScript

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

Не удается создать цикл Razor, JavaScript выходит за рамки

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

Я могу заставить его работать с

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

Но я не знаю, зачем мне использовать JSON.

Также, пока я ограничиваю это 255 байтами. В будущем он может набрать много МБ.

Том Мартин
источник
1
вы можете получить доступ к razor в js, но не наоборот
Эхсан Саджад

Ответы:

216

Это возможно, вам просто нужно пройтись по коллекции бритвы

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Надеюсь это поможет

Heymega
источник
За исключением того, что мне пришлось объявить свой массив, используя следующую запись var myArray = new Array ();
Том Мартин
Gald, это работает - Да, в противном случае он будет искать объект C # с именем myArray.
heymega
1
Большая помощь. Я думал, что у меня возникнут огромные проблемы с созданием объекта javascript из модельного словаря.
IAbstract
Спасибо! Мне это было нужно, потому что мне нужно было передать список строк в Javascript, а затем в Typescript для моего приложения Angular :)
Bluesight
@mmcrae @dобъявляется внутри цикла foreach. Обратите внимание, что перед d стоит термин VAR. Это позволяет использовать его внутри цикла foreach
JhWebDev
8

Синтаксис JSON в значительной степени является синтаксисом JavaScript для кодирования вашего объекта . Поэтому с точки зрения краткости и скорости ваш собственный ответ - лучший выбор.

Я использую этот подход при заполнении раскрывающихся списков в моей модели KnockoutJS . Например

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>

Обратите внимание, что я использую пакет NuGet Json.NET для сериализации и ViewBag для передачи данных.

Донал Лафферти
источник
8

Я работал со списком тостов (предупреждающих сообщений) List<Alert>из C # и нуждался в нем как массив JavaScript для Toastr в частичном представлении ( .cshtmlфайле). Приведенный ниже код JavaScript сработал для меня:

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

Я интегрировал слайдер и мне нужно было получить все файлы в папке, и у меня была такая же ситуация: массив C # с массивом javascript. Это решение от @heymega работало отлично, за исключением того, что мой парсер javascript раздражал при varиспользовании в foreachцикле. Поэтому я немного поработал, чтобы избежать петли.

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

И код javascript

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

Надеюсь, поможет

Али Умайр
источник
4

Чтобы развернуть ответ, получивший наибольшее количество голосов, для справки, если вы хотите добавить более сложные элементы в массив:

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

и т.п.

Кроме того, если вы хотите передать массив в качестве параметра своему контроллеру, вы можете сначала преобразовать его в строку:

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

McFroob
источник
Возникла проблема с вашим кодом. Должно быть @:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2");
Асад
1

Это был бы лучший подход, поскольку я реализовал :)

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

Надеюсь, это поможет вам предотвратить повторение модели (счастливое кодирование)

Мухаммад Эсса
источник
0

Если это симметричный (прямоугольный) массив, попробуйте вставить его в одномерный массив javascript; используйте бритву для определения структуры массива; а затем преобразовать в двумерный массив.

// 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);
}
Джон Арунделл
источник