2010-08-05 1 views
31

Tôi là yêu thích MVC 2. Toàn bộ nội dung chỉ phù hợp với web rất tốt.Làm cách nào để sử dụng Html.DisplayFor bên trong một trình lặp?

Có một mảnh chức năng, tuy nhiên, tôi không thể để dỗ ra khỏi Html.DisplayFor() chức năng:

<@ Page Inherits="ViewPage<IEnumerable<Foo>>"> 

<% foreach(var item in Model) { %> 

    <%: Html.DisplayFor(item.BarBaz) %> 

<% } %> 

tôi cần để có thể sử dụng DisplayTemplate cho giá trị này. Có cách nào để làm việc này không?

Trả lời

63

Thực ra, tôi đã tìm ra. Cách ngu ngốc của tôi.

này hoạt động:

<@ Page Inherits="ViewPage<IEnumerable<Foo>>"> 

<% foreach(var item in Model) { %> 

    <%: Html.DisplayFor(m => item.BarBaz) %> 

<% } %> 
+2

Tôi nghĩ rằng, tôi thậm chí còn ngu ngốc hơn, vì tôi không chắc chắn làm thế nào để giải thích điều này. Tham số chính thức lambda m không được sử dụng trong biểu thức. Vì vậy, điều này chỉ có bởi vì nó được yêu cầu bởi _DisplayFor_? Ngoài ra, tôi hy vọng rằng '@ Html.Display (item.BarBaz)' cũng hoạt động tốt, nhưng điều đó không làm gì cả. –

+0

@ R.Schreurs Có vẻ như lambda cần phải là một biểu thức 'Func' lấy kiểu của mô hình làm tham số, nhưng nó có thể trả về bất cứ thứ gì. – JohnnyHK

+0

Tôi cũng ngu ngốc :) –

10

Bạn có thể thực hiện nó bằng cách ra khỏi foreach và sử dụng thường xuyên cho vòng lặp:

<% for (int i = 0; i < Model.Count(); i++) { %> 

    <%: Html.DisplayFor(p=> p.ElementAt(i).BarBaz) %> 

<%} %> 

Một lựa chọn khác sẽ được tạo ra một PartialView diễn một đối tượng Foo và chỉ hiển thị những thông tin mà bạn muốn.

<% foreach (var item in Model) 
    { 
     Html.RenderPartial("FooBarBazLine", item); 
    } %> 
+1

tôi thích phương án 2 tốt hơn – Necros

+1

1 nhưng tôi với Necros/tùy chọn 2 là sạch hơn nhiều – Tahbaza

+1

Tôi đồng ý rằng tùy chọn 2 là một giải pháp tốt hơn. Tôi chỉ bao gồm tùy chọn 1 như tôi nghĩ về nó đầu tiên và không thực sự có bất kỳ lý do để loại bỏ nó vì nó giải quyết vấn đề. – sgriffinusa

3

Html.DisplayFor có thể tự động lặp qua các bộ sưu tập, trưng bày một cái nhìn cục bộ cho mỗi phần tử trong bộ sưu tập.

Điều đầu tiên bạn cần làm là tạo một lớp mô hình thực tế, với bộ sưu tập là thuộc tính của lớp.

public class Bar 
{ 
    public IEnumerable<Foo> foo { get; set; } 
} 

Trả lại lớp này từ bộ điều khiển của bạn thay vì thu thập nguyên liệu.

Thứ hai, bạn cần mẫu hiển thị cho lớp Foo. Các mẫu hiển thị là các khung nhìn một phần cần được đặt trong thư mục Views/Shared/DisplayTemplates.

Chỉnh sửa: Bạn cũng có thể có chúng trong thư mục con của trình điều khiển của Chế độ xem nếu bạn muốn giới hạn mẫu cho một bộ điều khiển cụ thể. Xem this question để biết thêm thông tin.

Dưới đây là một ví dụ trong cú pháp cạo:

@model YourNameSpace.Foo 
<p>@Model.BarBaz</p> 

Lưu nó như Foo.cshtml trong thư mục DisplayTemplates đưa ra ở trên.

Mẫu này khá đơn giản vì nó dựa trên ví dụ của bạn nơi bạn chỉ hiển thị một chuỗi, nhưng nếu các thành phần thu thập trong đó một lớp có thuộc tính riêng của nó, bạn có thể tạo một mẫu phức tạp hơn.

Bây giờ trong giao diện ban đầu, bạn có thể thoát khỏi vòng lặp hoàn toàn và chỉ cần viết

@Html.DisplayFor(m => m.foo) 

Thông báo foo là tên của thuộc tính trong lớp học mô hình mới của bạn có chứa bộ sưu tập cũ bạn looped kết thúc trước khi .

DisplayFor sẽ tự động biết rằng foo tài sản là loại (bộ sưu tập) Foo và nhặt Foo.cshtml mẫu trong thư mục DisplayTemplates và hiển thị nó một lần cho mỗi phần tử trong foo.

+0

Hãy tưởng tượng bạn có rất nhiều mô hình, có danh sách như thế này ** IEnumerable **. Bạn sẽ tạo một mẫu cho mỗi một nghìn thực thể? Tất cả những gì bạn cần chỉ là mẫu chung cho các kiểu cơ bản, như chuỗi, số nguyên, boolean, v.v. – Alexander

+0

Bạn không thực sự cần thanh, do đó, trong trường hợp bộ sưu tập foo có thể truy cập được không? Hoặc nó chỉ là một biến địa phương? – toddmo

6

Đây là một câu hỏi cũ, nhưng tôi đoán rằng ai đó có thể nhận được lợi ích từ giải pháp của tôi:

ASPX xem

<%@ Page Inherits="ViewPage<IEnumerable<Foo>>" %> 

<% foreach (var item in Model) { %> 

    <%: Html.DisplayFor(m => item) %> 

<% } %> 

Razor view

@model IEnumerable<Foo> 

@foreach (var item in Model) 
{ 
    Html.DisplayFor(m => item) 
} 

Kể từ DisplayFor chấp nhận một lambda nhập ngầm, chúng ta có thể trực tiếp chỉ ra instanc e để hiển thị trong vòng lặp.

Cuối cùng, tôi đồng ý với câu trả lời Anders E. Andersen 's cho mẫu sử dụng

0

Trong Razor Tôi đang sử dụng

@Html.DisplayFor(model => item.CreatedDate)