2013-03-08 36 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

すばやく詳細な答えをありがとう!しかし、IEnumerable部分を除いて、次のエラー「ラムダ式を動的ディスパッチ演算の引数として使用できません...」が表示されます。その部分を追加すると、「メソッドの型引数は使用法から推論できません」というエラーが表示されます。助けてくれてありがとう、そしてこれがルーキーミスであればごめんなさい。 p.s.私はこのページのビュー・モデルを使用しています。そのため、ビュー・バッグを使用しています。 – Matt

+0

しかし、ビューモデルは、ビューの要件を満たすために特別に設計したクラスです。この場合、ビューにはこの動的javascriptを生成する必要があります。そのため、ビューモデルには、 'IEnumerable '型のコレクションプロパティが含まれている必要があります。そして、単にキャスト全体を 'Model.Users.Select(...)'に置き換えてください。弱く型付けされたViewBagを残しておけば、適切な 'IEnumerable '型にキャストする必要があります。 –

+0

私はすぐにページを修正し、Viewモデルを使用しました。私はまたあなたの答えの別の1つを参照する必要がありましたhttp://stackoverflow.com/questions/12111729/razor-javascript-and-trailing-semicolon、VS2012でこのバグについて知りませんでした。偉大で有益な答えをありがとう! – Matt

2

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

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

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

チップのおかげで、私もこれを試してみる:) – Matt

1

@ダリン・ディミトロフ答えが上にあります。もし誰かがビューバックではなくモデルを渡しているなら、私はそれに追加したいと思います。

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

の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とは何かに大規模な拡張性を作り出します。

関連する問題