2013-03-08 50 views
10

Tôi có danh sách người dùng mà tôi chuyển từ bộ điều khiển của mình sang chế độ xem bằng cách sử dụng túi xem. Bây giờ tôi cần để có thể vượt qua cùng một danh sách để javascript trên trang. Tôi có thể tạo lại danh sách bằng cách sử dụng vòng lặp foreach:Danh sách chuyển từ MVC ViewBag sang 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> 
} 

Tuy nhiên, điều này có vẻ như một cách tiếp cận lộn xộn và yêu cầu nhiều việc phải làm lại nếu có thay đổi. Tôi biết có những bài viết tương tự trên Stack tràn, nhưng rất nhiều người trong số họ sử dụng phiên bản trước của MVC và cú pháp tương tự dường như không áp dụng. Ý tưởng nào?

Trả lời

20

Bạn có thể làm điều đó trong một dòng mã đơn lẻ và an toàn bằng cách sử dụng trình phân tích cú pháp JSON. Bạn hoàn toàn không bao giờ nên tự xây dựng JSON với một số chuỗi và các công cụ như bạn đã cố gắng làm trong ví dụ của mình. Không cần phải viết bất kỳ vòng nào.

Dưới đây là cách chính xác để làm điều đó:

<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 được tạo sẽ xem xét một cách chính xác như bạn mong đợi:

<script type="text/javascript"> 
    var array = [{"userId":1,"userLat":10,"userLon":15}, {"userId":2,"userLat":20,"userLon":30}, ...]; 
    alert(array[0].userId); 
</script> 

Tất nhiên cấp độ tiếp theo của sự cải tiến trong mã này được để thoát khỏi của ViewCrap và sử dụng kiểu xem mạnh mẽ.

+0

Cảm ơn câu trả lời nhanh chóng và chi tiết! Nhưng tôi nhận được lỗi sau đây 'Không thể sử dụng một biểu thức lambda như một đối số cho một hoạt động gửi động ...' mà không có phần IEnumerable. Với phần đó được thêm vào, tôi cũng gặp lỗi 'Các đối số kiểu cho phương thức ... không thể suy ra từ việc sử dụng'. Cảm ơn bạn đã giúp đỡ, và xin lỗi nếu đây là một sai lầm tân binh. p.s. Tôi đang sử dụng mô hình xem cho một cái gì đó khác trên trang này, đó là lý do tại sao tôi đang sử dụng túi xem. – Matt

+0

Nhưng mô hình chế độ xem là một lớp mà bạn đặc biệt thiết kế để đáp ứng các yêu cầu của chế độ xem của bạn. Trong trường hợp này, chế độ xem của bạn có yêu cầu tạo javascript động này. Vì vậy, mô hình khung nhìn của bạn nên chứa thuộc tính bộ sưu tập của loại 'IEnumerable '. Và sau đó chỉ cần thay thế toàn bộ diễn viên bằng 'Model.Users.Select (...)'.Nếu bạn rời khỏi ViewBag bị đánh máy yếu, bạn sẽ cần phải đưa nó vào loại 'IEnumerable ' thích hợp. –

+0

Ok Tôi đã nhanh chóng sửa đổi trang và sử dụng mô hình Xem và nó hoạt động. Tôi cũng phải tham khảo một câu trả lời khác của bạn http://stackoverflow.com/questions/12111729/razor-javascript-and-trailing-semicolon, không biết về lỗi này trong VS2012. Cảm ơn câu trả lời tuyệt vời và thông tin! – Matt

2

Một tùy chọn khác, có thể là tạo hành động mới trong bộ điều khiển của bạn để trả về JsonResult. Kết quả json này có thể trả về danh sách của bạn. Trong trang của bạn, bạn có thể gọi hành động với jquery và sử dụng nó từ đó.

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

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

Cảm ơn bạn đã tip, tôi cũng sẽ thử điều này :) – Matt

1

@Darin Câu trả lời Dimitrov được bật. Tôi chỉ muốn thêm vào nó nếu bất cứ ai đi qua một mô hình và không phải là một watchbag.

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

Trường hợp sử dụng của tôi là cụ thể cho select2. Một sau đó có thể chỉ cần vượt qua mảng số liệu: attribute

$("#storeSelect").select2({ 
     data: array, 
     placeholder: "Select something" 
}); 
</script> 

viewmodel

public class YourViewModel 
    { 
    public IEnumarable<YourPoco> YourPocos { get; set; } 
    } 

khiển

public class YourController : Controller 
{ 
    public ActionResult Index() 
    { 
     YourViewModel vm = new YourViewModel{ 
      // Using Dependancy injection 
      YourPocos = yourRepo.GetYourPocos(); 
     }; 
     return View("Index", "_Layout",vm); 
    } 
} 

Tôi nhận ra câu trả lời này có thể là không cần thiết, nhưng nó là lần đầu tiên tôi đang sử dụng Json.Encode và chuyển các giá trị mô hình sang phần mở rộng jquery. Điều này cho tôi là quá mát mẻ. Nó ở một mức độ nhất định tạo ra khả năng mở rộng lớn về những gì nếu không sẽ là một @htmlhelper

Các vấn đề liên quan