将列表从 MVC ViewBag 传递给 JavaScript
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15291566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing list from MVC ViewBag to JavaScript
提问by Matt
I have a list of users which I pass from my controller to my view using the view bag. Now I need to be able to pass the same list to the javascript on the page. I could reconstruct the list using a foreach loop:
我有一个用户列表,我使用视图包从我的控制器传递到我的视图。现在我需要能够将相同的列表传递给页面上的 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>
}
However this seems like a messy approach and required a lot of reworking if a change is made. I know there are similar posts on Stack overflow, but a lot of them use previous version of MVC and the same syntax doesn't seem to apply. Any ideas?
然而,这似乎是一种凌乱的方法,如果进行更改,则需要进行大量返工。我知道在 Stack Overflow 上有类似的帖子,但其中很多都使用以前版本的 MVC,并且相同的语法似乎并不适用。有任何想法吗?
回答by Darin Dimitrov
You could do that in a single and safe line of code using a JSON parser. You should absolutely never manually build JSON with some string concatenations and stuff as you attempted to do in your example. No need to write any loops as well.
您可以使用 JSON 解析器在一行安全的代码中完成此操作。您绝对不应该像您在示例中尝试做的那样手动构建带有一些字符串连接和内容的 JSON。也不需要编写任何循环。
Here's the correct way to do that:
这是正确的方法:
<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>
The generated HTML will look exactly as you expect:
生成的 HTML 将完全符合您的预期:
<script type="text/javascript">
var array = [{"userId":1,"userLat":10,"userLon":15}, {"userId":2,"userLat":20,"userLon":30}, ...];
alert(array[0].userId);
</script>
Of course the next level of improvement in this code is to get rid of the ViewCrap
and use a strongly typed view model.
当然,此代码的下一级改进是摆脱ViewCrap
并使用强类型视图模型。
回答by gdp
Another option, could be to create a new action in your controller returning a JsonResult. This json result could return your list. In your page you can call the action with jquery and use it from there.
另一种选择是在您的控制器中创建一个返回 JsonResult 的新操作。此 json 结果可能会返回您的列表。在您的页面中,您可以使用 jquery 调用该操作并从那里使用它。
public ActionResult GetMyList()
{
var list = GetMyUserList();
return Json(new { userlist = list }, JsonRequestBehaviour.AllowGet);
}
回答by gdp
@Darin Dimitrov answer is spot on. I would just like to add to it if anyone is passing a model and not a viewbag.
@Darin Dimitrov 的回答很到位。如果有人传递模型而不是视图包,我只想添加它。
<script type="text/javascript">
var array = @Html.Raw(Json.Encode(
Model.YourModel.Select(_ => new {
id = _.Id,
text = _.Name
})
))
My use case was specific to select2. One can then just pass the array to the data: attribute
我的用例特定于select2。然后可以将数组传递给 data: 属性
$("#storeSelect").select2({
data: array,
placeholder: "Select something"
});
</script>
viewmodel
视图模型
public class YourViewModel
{
public IEnumarable<YourPoco> YourPocos { get; set; }
}
Controller
控制器
public class YourController : Controller
{
public ActionResult Index()
{
YourViewModel vm = new YourViewModel{
// Using Dependancy injection
YourPocos = yourRepo.GetYourPocos();
};
return View("Index", "_Layout",vm);
}
}
I realise this answer might be redundant, but it is the first time i am using Json.Encode and passing model values to a jquery extension. This for me is too cool. It does to a certain degree create massive extensibility on what would otherwise be an @htmlhelper
我意识到这个答案可能是多余的,但这是我第一次使用 Json.Encode 并将模型值传递给 jquery 扩展。这对我来说太酷了。它确实在某种程度上为 @htmlhelper 创造了巨大的可扩展性