Razor MVC:使用模型数组填充JavaScript数组

119

我正在尝试使用模型中的数组来加载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字节内,但未来可能会达到数MB。


1
你可以在 JavaScript 中访问 Razor,但反之则不行。 - Ehsan Sajjad
12个回答

256

这是可能的,你只需要遍历刀片集合。

<script type="text/javascript">

    var myArray = [];

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

    alert(myArray);

</script>

除了我必须使用以下符号声明我的数组 var myArray= new Array(); - Tom Martin
很高兴它有效 - 是的,否则它会寻找一个名为myArray的C#对象。 - heymega
2
非常有帮助。我原以为从模型字典构建JavaScript对象会遇到很大的问题。 - IAbstract
谢谢!我需要这个,因为我必须将一个字符串列表传递给Javascript,然后传递给我的Angular应用程序的Typescript :) - Bluesight
@mmcrae,@d在foreach循环内部声明。请注意,d前面有一个VAR术语。这使它可以在foreach循环内部使用。 - JhWebDev
1
请注意,如果您的数组项包含引号或反斜杠,则此代码将使JavaScript无效。解决方法是使用:@:myArray.push("@Html.Raw(HttpUtility.JavaScriptStringEncode(d))"); - Allie

14

我正在使用C#中的一个toast列表(警告消息)List<Alert>,并需要它作为JavaScript数组用于部分视图(.cshtml文件)中的Toastr。以下是我使用的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);
});

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>

请注意,我使用Json.NET NuGet 包进行序列化,并使用 ViewBag 传递数据。

6

为了进一步解释得票最高的答案,如果您想向数组中添加更复杂的项目:

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

等等。

此外,如果您想将该数组作为参数传递给您的控制器,您可以首先将其转换为字符串:

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


你的代码有问题。应该是:@:myArray.push(ClassMember1: "@d.ClassMember1", ClassMember2: "@d.ClassMember2"); - Asad
现在看起来数组代码应该是@:myArray.push({ClassMember1: "@d.CassMember1", ClassMember2: "@d.ClassMember2"}),所有成员周围的{...}是必需的。 - Paul Gibson

4

我正在集成一个滑块,并需要获取文件夹中的所有文件,遇到了与C#数组到JavaScript数组相同的情况。这个解决方案由@heymega提供,非常完美,但我的JavaScript解析器对foreach循环中的var使用感到恼火。因此,我进行了一些绕路以避免循环。

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

希望它有所帮助。

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>

希望这能帮助你避免对模型进行迭代(愉快编程)。

1

带有命名字段的有效语法:

  var array = [];

     @foreach (var item in model.List)
     {
        @:array.push({ 
                       "Project": "@item.Project",
                       "ProjectOrgUnit": "@item.ProjectOrgUnit"
                     });
     }

当我按照你分享的代码进行尝试时,出现了一个错误。但是当我将代码写成foreach循环的一行时,它就正常工作了。 - undefined

0

也许这个简单的解决方案也很有趣,而且可以轻松地应用到JavaScript字典中:

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

这将被翻译成以下内容(在这里,string1到stringN被视为Model.data的内容)

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

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

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

控制器/操作 参数:ICollection<_Model> _items


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接