2009-03-13 31 views
9

Phương thức 'RenderPartial()' trong ASP.NET MVC cung cấp một mức chức năng rất thấp. Nó không cung cấp, cũng không cố gắng cung cấp một mô hình 'bộ điều khiển phụ' thực sự *.ModelFactory trong ASP.NET MVC để giải quyết vấn đề 'RenderPartial'

Tôi có số lượng kiểm soát ngày càng tăng được hiển thị qua 'RenderPartial()'. Họ rơi vào 3 loại chính:

1) Điều khiển được trực tiếp hậu duệ của một trang cụ thể mà sử dụng mô hình của trang đó

2) Điều khiển được trực tiếp hậu duệ của một trang cụ thể mà sử dụng mô hình của trang đó với một số additional key of some type. Hãy suy nghĩ triển khai 'DataRepeater'.

3) Kiểm soát đại diện cho các chức năng không liên quan đối với trang chúng xuất hiện . Đây có thể là bất kỳ điều gì từ máy quay biểu ngữ , tới biểu mẫu phản hồi, công cụ định vị cửa hàng, đăng ký danh sách gửi thư. Điểm mấu chốt là nó không quan tâm trang nào được đưa lên.

Do cách thức các công trình mô hình ViewData chỉ tồn tại một đối tượng mô hình theo yêu cầu - có nghĩa là phải nói bất kỳ điều khoản phụ nào cần phải có trong mô hình trang.

Cuối cùng nhóm MVC hy vọng sẽ xuất hiện với mô hình 'subcontroller' thực sự, nhưng cho đến lúc đó tôi chỉ thêm bất kỳ thứ gì vào mô hình trang chính mà các điều khiển con cũng cần.

Trong trường hợp (3) trên đây có nghĩa là mô hình của tôi cho 'ProductModel' có thể phải chứa một trường cho mô hình 'MailingListSignup'. Rõ ràng đó không phải là lý tưởng, nhưng tôi đã chấp nhận điều này với sự thỏa hiệp tốt nhất với khung công tác hiện tại - và ít nhất là có khả năng 'đóng bất kỳ cửa' nào cho một mô hình bộ điều khiển tương lai.

Bộ điều khiển phải chịu trách nhiệm lấy dữ liệu cho mô hình vì mô hình thực sự chỉ là cấu trúc dữ liệu câm mà không biết nó lấy dữ liệu từ đâu. Nhưng tôi không muốn bộ điều khiển phải tạo mô hình ở nhiều nơi khác nhau.

Điều tôi đã bắt đầu làm là tạo một nhà máy để tạo cho tôi mô hình. Nhà máy này được gọi bởi bộ điều khiển (mô hình không biết về nhà máy).

public static class JoinMailingListModelFactory { 

     public static JoinMailingListModel CreateJoinMailingListModel() { 

      return new JoinMailingListModel() 
      { 
       MailingLists = MailingListCache.GetPartnerMailingLists(); 
      }; 
     } 
    } 

Vì vậy, câu hỏi thực tế của tôi là như thế nào những người khác với vấn đề này cùng thực sự tạo ra các mô hình. Điều gì sẽ là cách tiếp cận tốt nhất cho tương thích trong tương lai với các tính năng mới của MVC?


  • NB: Có vấn đề với RenderAction() rằng tôi sẽ không đi vào đây - không kém phần quan rằng nó chỉ trong MVCContrib và sẽ không được trong phiên bản RTM của ASP.NET MVC-. Các vấn đề khác gây ra sufficent problems mà tôi đã chọn không sử dụng nó. Vì vậy, cho phép giả vờ cho bây giờ mà chỉ có RenderPartial() tồn tại - hoặc ít nhất đó thats những gì tôi đã quyết định sử dụng.

Trả lời

2

Một phương pháp tôi đã thấy trong trường hợp này là sử dụng bộ lọc hành động để điền dữ liệu cho chế độ xem một phần - tức làlớp con ActionFilterAttribute. Trong các OnActionExecuting, thêm dữ liệu vào ViewData. Sau đó, bạn chỉ cần trang trí các hành động khác nhau mà sử dụng chế độ xem một phần với bộ lọc.

+0

tôi càng nghĩ về điều này thì tôi càng ít thích ý tưởng này hơn. sau đó tôi càng nghĩ về nó sau đó càng có nhiều DID thích nó. chủ yếu là vì dễ dàng hơn cho bất kỳ ai để thêm điều khiển vào trang - chỉ cần thêm thuộc tính và RenderPartial và bạn đã hoàn tất. –

+0

Điều đó nghe có vẻ như rất nhiều suy nghĩ ;-p –

+0

đã kết thúc bằng cách sử dụng phương pháp này ở một số nơi trong ứng dụng của tôi. làm cho nó sạch hơn nhiều để áp dụng những điều nhất định cho các mô hình trên toàn cầu. tôi sử dụng cả hai cho một 'mô hình cơ sở' tương ứng với một trang chủ và cũng 'mô hình khu vực' cho các khu vực khác nhau trong trang web. khá linh hoạt và trong khi tôi không hoàn toàn trong tình yêu với tiêm những thứ vào mô hình của tôi nó đang làm việc khá tốt –

1

Có một tình trạng quá tải renderPartial tôi sử dụng mà cho phép của bạn chỉ định một ViewData mới và mẫu:

RenderPartial code

Nếu bạn nhìn vào các liên kết trước đó của mã nguồn MVC, cũng như sau (tìm kiếm phương pháp RenderPartialInternal):

RenderPartialInternal code

bạn có thể thấy rằng nếu về cơ bản bản ViewData bạn vượt qua việc tạo ra một từ điển mới và thiết lập mô hình được sử dụng trong các điều khiển. Vì vậy, trang có thể có một mô hình, nhưng sau đó vượt qua một mô hình khác nhau để kiểm soát phụ.

Nếu các điều khiển phụ không được chuyển trực tiếp từ Mô hình chế độ xem chính, bạn có thể thực hiện thủ thuật mà Marc Gravell đề cập để thêm logic tùy chỉnh của bạn.

5

Thay vì thêm những thứ như MailingListSignup như một tài sản của ProductModel của bạn, đóng gói cả hai cùng cấp trong một lớp học như ProductViewModel trông giống như:

public class ProductViewModel() { 
    public ProductModel productModel; 
    public MailingListSignup signup; 
} 

Sau đó được xem của bạn được mạnh mẽ-gõ vào ProductViewModel lớp học. Bạn có thể truy cập vào số ProductModel bằng cách gọi Model.productModel và bạn có thể truy cập vào lớp đăng ký bằng cách sử dụng Model.signup.

Đây là giải thích lỏng lẻo về 'Mô hình trình bày' của Fowler (http://martinfowler.com/eaaDev/PresentationModel.html), nhưng tôi đã thấy nó được một số nhà phát triển Microsoft sử dụng, chẳng hạn như Rob Conery và Stephen Walther.

+1

Tôi thường tham khảo asp.net MVC như MVVC :) –

+0

Đây thường là cách tiếp cận tôi thực hiện, nhưng nó vẫn có mùi vui với tôi.Tôi không thích thực tế rằng khung nhìn bên ngoài đã được cung cấp dữ liệu mà nó không cần. Tôi đã thực hiện để sử dụng Html.RenderAction () mà có vẻ tốt hơn so với Html.RenderPartial() như là một proxy cho bộ điều khiển phụ thực sự nhưng nó vẫn còn hơi yếu. –

+0

@ James, tôi làm theo cách của bạn, nơi productModel và SignUpModel là các mô hình dữ liệu thực tế. Nhưng tôi thấy mình mất đi lợi ích của các chú thích xác nhận. Tôi sử dụng tính năng Xác thực thông thạo để xác thực mọi thứ ở cấp tên miền, có vẻ không sao. – Tom

0

Một phương pháp tôi đã thử là sử dụng chế độ xem một phần được nhập mạnh mẽ với giao diện. Trong hầu hết các trường hợp, ViewModel được canh tác là cách tốt hơn, nhưng tôi vẫn muốn chia sẻ điều này.

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<IMailingListSignup>" %> 

ViewModel thực hiện giao diện

public class ProductViewModel:IMailingListSignup 

Thats không hoàn hảo ở tất cả nhưng giải quyết được một số vấn đề: Bạn vẫn có thể dễ dàng lập bản đồ thuộc tính từ tuyến đường của bạn với mô hình. Tôi không shure nếu bạn có thể có một bản đồ tham số tuyến đường đến các thuộc tính của MailingListSignup nếu không.

Bạn vẫn gặp sự cố khi điền Mô hình. Nếu nó không muộn, tôi thích làm điều đó trong OnActionExecuted. Tôi không thấy làm thế nào bạn có thể điền vào một mô hình trong OnActionExecuting.

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