web-dev-qa-db-ja.com

MVCViewBagから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を使用しており、同じ構文が適用されていないようです。何か案は?

12
Matt

JSONパーサーを使用して、1行の安全なコードでこれを行うことができます。例で試みたように、文字列の連結などを使用して手動で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を取り除き、強く型付けされたビューモデルを使用することです。

21
Darin Dimitrov

別のオプションは、JsonResultを返すコントローラーで新しいアクションを作成することです。このjsonの結果は、リストを返す可能性があります。ページで、jqueryを使用してアクションを呼び出し、そこから使用できます。

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

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

@DarinDimitrovの答えは的を射ています。誰かがビューバッグではなくモデルを渡している場合は、それに追加したいと思います。

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

私のユースケースは select2 に固有のものでした。次に、配列をdata:属性に渡すだけです。

 $("#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になるものに大規模な拡張性を作成します

1
user1752532