将MVC ViewBag中的列表传递给JavaScript

时间:2013-03-08 10:15:16

标签: javascript asp.net-mvc-4 viewbag

我有一个用户列表,我使用视图包从控制器传递到我的视图。现在我需要能够将相同的列表传递给页面上的javascript。我可以使用foreach循环重建列表:

    @foreach (var item in ViewBag.userList) //Gets list of users passed from controller and adds markers to the map
{
    var userLat = item.LastLatitude;
    var userLon = item.LastLongitude;
    var _userId = item.Id;

    <script>array.push({"userId":"'@_userId'","userLat":"'@userLat'","userLon":"'@userLon'"});</script>
}

然而,这似乎是一种混乱的方法,如果做出改变则需要进行大量的改造。我知道Stack溢出有类似的帖子,但是很多都使用以前版本的MVC,并且相同的语法似乎不适用。有什么想法吗?

3 个答案:

答案 0 :(得分:21)

您可以使用JSON解析器在单个且安全的代码行中执行此操作。你绝对不应该像你试图在你的例子中那样用一些字符串连接和东西手动构建JSON。也不需要编写任何循环。

这是正确的方法:

<script type="text/javascript">
    var array = @Html.Raw(
        Json.Encode(
            ((IEnumerable<UserModel>)ViewBag.userList).Select(user => new 
            { 
                userId = user.Id, 
                userLat = user.LastLatitude, 
                userLon = user.LastLongitude 
            })
        )
    );

    alert(array[0].userId);
</script>

生成的HTML看起来完全符合您的期望:

<script type="text/javascript">
    var array = [{"userId":1,"userLat":10,"userLon":15}, {"userId":2,"userLat":20,"userLon":30}, ...];
    alert(array[0].userId);
</script>

当然,此代码的下一级改进是摆脱ViewCrap并使用强类型视图模型。

答案 1 :(得分:2)

另一种选择,可能是在你的控制器中创建一个返回JsonResult的新动作。这个json结果可以返回你的列表。在您的页面中,您可以使用jquery调用该操作并从那里使用它。

public ActionResult GetMyList()
{
    var list = GetMyUserList();

    return Json(new { userlist = list }, JsonRequestBehaviour.AllowGet);
}

答案 2 :(得分:1)

@Darin Dimitrov回答是现货。如果有人传递模型而不是视图包,我只想添加它。

<script type="text/javascript">
 var array = @Html.Raw(Json.Encode(
            Model.YourModel.Select(_ => new {
              id = _.Id,
              text = _.Name
            })
          ))

我的用例特定于select2。然后可以将数组传递给data:attribute

 $("#storeSelect").select2({
        data: array,
        placeholder: "Select something"
 });
</script>

<强>视图模型

public class YourViewModel
  {
    public IEnumarable<YourPoco> YourPocos { get; set; }
  }

<强>控制器

public class YourController : Controller
{
    public ActionResult Index()
    {
        YourViewModel vm = new YourViewModel{
            // Using Dependancy injection
            YourPocos = yourRepo.GetYourPocos();
        };
        return View("Index", "_Layout",vm);
    }
}

我意识到这个答案可能是多余的,但这是我第一次使用Json.Encode并将模型值传递给jquery扩展。这对我来说太酷了。它确实在某种程度上为@htmlhelper

创造了大量的可扩展性