2013-03-08 282 views
10

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

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

然而,这似乎是一个混乱的方法,并要求很多,如果一个变化是由再加工的。我知道堆栈溢出中有类似的帖子,但是很多人使用MVC的先前版本,并且相同的语法似乎不适用。有任何想法吗?

回答

20

您可以使用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,并使用强类型视图模型。

+0

感谢您的快速和详细的答案!但是,我得到以下错误:'不能使用lambda表达式作为动态分派操作的参数...'而没有IEnumerable部分。添加该部分后,我也得到一个错误'方法的类型参数...不能从用法推断'。谢谢你的帮助,如果这是一个新手的错误,很抱歉。附:我在此页面上使用视图模型来实现其他功能,这就是我使用视图包的原因。 – Matt 2013-03-08 10:28:51

+0

但是,视图模型是您专门设计以满足您的视图要求的类。在这种情况下,您的视图需要生成此动态JavaScript。所以你的视图模型应该包含'IEnumerable '类型的集合属性。然后用'Model.Users.Select(...)'替换整个演员阵容。如果您离开弱类型ViewBag,则需要将其转换为正确的“IEnumerable ”类型。 – 2013-03-08 10:33:10

+0

好吧,我很快修改了页面,并使用了View模型,它工作。我也不得不参考另一个你的答案http://stackoverflow.com/questions/12111729/razor-javascript-and-trailing-semicolon,不知道VS2012中的这个错误。感谢您提供的信息丰富的答案! – Matt 2013-03-08 10:42:30

2

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

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

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

感谢您的提示,我会试试这:) – Matt 2013-03-08 10:44:06

1

@Darin Dimitrov answer is spot on。如果有人传递模型而不是视图包,我只想补充一下。

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

我的用例是特定于select2。人们可以那么阵列只是传递到数据:属性

$("#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

相关问题