简体   繁体   中英

Razor MVC Populating Javascript array with Model Array

I'm trying to load a JavaScript array with an array from my model. Its seems to me that this should be possible.

Neither of the below ways work.

Cannot create a JavaScript loop and increment through Model Array with JavaScript variable

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

Cannot create a Razor loop, JavaScript is out of scope

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

I can get it to work with

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

But I don't know why I should have to use JSON.

Also while at the moment I'm restricting this to 255 bytes. In the future it could run into many MBs.

This is possible, you just need to loop through the razor collection

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

Hope this helps

I was working with a list of toasts (alert messages), List<Alert> from C# and needed it as JavaScript array for Toastr in a partial view ( .cshtml file). The JavaScript code below is what worked for 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);
});

JSON syntax is pretty much the JavaScript syntax for coding your object . Therefore, in terms of conciseness and speed, your own answer is the best bet.

I use this approach when populating dropdown lists in my KnockoutJS model . Eg

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>

Note that I'm using Json.NET NuGet package for serialization and the ViewBag to pass data.

To expand on the top-voted answer, for reference, if the you want to add more complex items to the array:

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

etc.

Furthermore, if you want to pass the array as a parameter to your controller, you can stringify it first:

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

I was integrating a slider and needed to get all the files in the folder and was having same situationof C# array to javascript array.This solution by @heymega worked perfectly except my javascript parser was annoyed on var use in foreach loop. So i did a little work around avoiding the 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());

And the javascript code is

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

Hope it helps

This would be better approach as I have implemented :)

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

Hope this will help you to prevent you from iterating model ( happy coding )

If it is a symmetrical (rectangular) array then Try pushing into a single dimension javascript array; use razor to determine the array structure; and then transform into a 2 dimensional array.

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

The valid syntax with named fields:

  var array = [];

     @foreach (var item in model.List)
     {
        @:array.push({ 
                       "Project": "@item.Project",
                       "ProjectOrgUnit": "@item.ProjectOrgUnit"
                     });
     }
@functions
{
    string GetStringArray()
    {
        var stringArray = "[";

        for (int i = 0; i < Model.List.Count; i++)
        {
            if (i != Model.List.Count - 1)
            {
                stringArray += $"'{Model.List[i]}', ";
            }
            else
            {
                stringArray += $"'{Model.List[i]}']";
            }
        }

        return stringArray;
    }
}

<script>
    var list = @Html.Raw(GetStringArray());
</script>

Maybe it could be interesting also this easy solution that can be easily applied also to javascript dictionaries:

<script type="text/javascript">
    var myArray = [
    @foreach (var d in Model.data)
    {
        @:"@d",
    }
    ];
</script>

that translates into this (string1 to stringN are considered here the content of Model.data)

<script type="text/javascript">
    var myArray = [
        "string1",
        "string2",
        "string3",
        ...
        "stringN",
    ];
</script>
<script>
    var tempArray = [];

    @foreach (var item in Model.Collection)
    {
        @:tempArray.push({ Field1: "@item.Field1", Field2: "@item.Field2" });
    }

    $("#btn").on("click", function () {
        $.ajax({
            url: '/controller/action',
            type: 'POST',
            contentType: 'application/json; charset=utf-8',
            data: JSON.stringify(tempArray),
            success: function (resp) {
                alert(resp);
            }
        });
    });
</script>

Controller/Action parameter: ICollection <_Model> _items

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM