我有一个用户列表,我使用视图包从控制器传递到我的视图。现在我需要能够将相同的列表传递给页面上的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,并且相同的语法似乎不适用。有什么想法吗?
答案 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)
<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
创造了大量的可扩展性