Передача списка из MVC ViewBag в JavaScript
У меня есть список пользователей, которые я передаю от своего контроллера к моему представлению, используя сумку просмотра. Теперь мне нужно иметь возможность передать тот же список в 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>
}
Однако это похоже на беспорядочный подход и требует много переделок, если сделано изменение. Я знаю, что есть аналогичные сообщения о переполнении стека, но многие из них используют предыдущую версию MVC, и такой синтаксис, похоже, не применяется. Любые идеи?
Ответы
Ответ 1
Вы можете сделать это в одной и безопасной строке кода, используя парсер 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
и использовать сильно типизированную модель представления.
Ответ 2
Другим вариантом может быть создание нового действия в контроллере, возвращающего JsonResult. Этот результат json может вернуть ваш список. На своей странице вы можете вызвать действие с помощью jquery и использовать его оттуда.
public ActionResult GetMyList()
{
var list = GetMyUserList();
return Json(new { userlist = list }, JsonRequestBehaviour.AllowGet);
}
Ответ 3
@Дарин Димитров отвечает на вопрос. Я просто хотел бы добавить к нему, если кто-то передаст модель, а не сумасшедшую.
<script type="text/javascript">
var array = @Html.Raw(Json.Encode(
Model.YourModel.Select(_ => new {
id = _.Id,
text = _.Name
})
))
Мой пример использования был специфичным для select2. Затем можно просто передать массив данным: attribute
$("#storeSelect").select2({
data: array,
placeholder: "Select something"
});
</script>
ViewModel
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