2014-10-07 82 views
0

我在創建自定義HTML助手時利用內置助手呈現特定節時遇到了困難。 (想想複合助手。)另外,助手只對特定的類有用。使用內置助手的特定類的自定義Html助手

考慮下面的類摘錄

public class Notification { 
    [Display("Notice")] 
    public string Content { get; set; } 
    public DateTime Created { get; set; } 
    public bool RequiresAcknowledgement { get; set; } 
} 

我想使下面的示例輸出

<div class="notification"> 
    <!-- Notice that the DateTime property only displays the Date portion (i.e. Created.Date) --> 
    <div class="notification-timestamp">Monday, October 07, 2014</div> 
    <div class="notification-content"> 
     <h1>Notice</h1> 
     This is a sample notice 
    </div> 
    <!-- This div is optional and only rendered if RequiresAcknowledgement == true --> 
    <div class="notification-acknowledgement"> 
     <input type="checkbox">By clicking this you acknowledge that you have read the notice 
    </div> 
</div> 

我想,我的擴展方法將有相似

public static System.Web.Mvc.MvcHtmlString DisplayNotificationFor<TModel, TValue>(this System.Web.Mvc.HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TValue>> expression) 
簽名

但我不確定我是否需要TModel和/或TValue,因爲我知道該方法僅適用於通知對象。

該簽名也導致混亂,當我試着做以下

// is this the correct way to get my model?? 
var valueGetter = expression.Compile(); 
var model = valueGetter(helper.ViewData.Model) as Notification; 

var timestamp = new System.Web.Mvc.TagBuilder("div"); 
timestamp.AddCssClass("notification-timestamp"); 

timestamp.InnerHtml = helper.DisplayFor(?????)  // What is the best way to output model.Created.Date? 

// how about 
// does not work/compile but shown as possible approach 
timestamp.InnerHtml = new System.Web.Mvc.Html.DisplayExtensions.DisplayFor<Notification, TValue>(helper, n => n.Created.Date); 

我明白,上面顯示的示例輸出大多隻是渲染只讀文本,這樣我可以呈現的特性通知對象直接而不是使用內置的幫助器方法,但我所問的問題也可以應用於可編輯的表單。例如,允許創建和/或修改通知的表單。

爲什麼我想再利用現有傭工的原因是,他們已經有渲染不同類型的根據數據類型(字符串VS布爾VS日期時間VS電子郵件)輸入的支持,他們支持驗證屬性,他們支持標籤的顯示屬性等。

當然,我想擴展我的簡單示例,以允許自定義屬性傳入像特定的ID或額外的CSS類。

我的方式與我應該如何使用/創建自定義html助手的基礎?

+0

如果它對於一個特定的類,那麼你可以只傳遞一個參數到''public static MvcHtmlString DisplayNotificationFor (HtmlHelper helper,Notification notification)''但爲什麼不只是創建一個'DisplayTemplate'爲'Notification.cs'? – 2014-10-11 07:31:11

+0

@StephenMuecke - 我不能使用DisplayTemplate,因爲我試圖創建一個可跨項目使用的庫項目(即多個MVC應用程序)。據我所知,顯示/編輯器模板(如部分視圖)只在定義它們的MVC應用程序中可用。我錯了嗎? – Jason 2014-10-14 19:56:32

+0

不知道將模板複製到'Views/Shared/DisplayTemplates'比添加引用到你的庫和更新web.config文件更困難,但我會很快發佈一個使用html助手的答案 – 2014-10-15 01:06:54

回答

0

原來,限制表達式的類比我想的要容易。

public static System.Web.Mvc.MvcHtmlString DisplayNotificationFor<TModel, TValue>(this System.Web.Mvc.HtmlHelper<TModel> helper, System.Linq.Expressions.Expression<Func<TModel, TValue>> expression) 
    where TValue: Notification { 

關鍵是附加到最後的泛型約束。

,可以讓我做

@model Common.Notifications.Notification 

@Html.DisplayNotificationFor(model => model) 

// or 

@model SomeViewModel 

@Html.DisplayNotificationFor(model => model.ImportantNotification) 

@Html.DisplayNotificationFor(model => model.SomeStringProperty) 

顯示爲設計時錯誤。

+0

正如我在我的答案中所述,您可以使用'System.Web.Mvc.Html.InputExtensions.CheckBox(...)'或'.CheckBoxFor(...)'這些內置的幫助程序。我只是根據你發佈的_sample output_創建了一個幫助器(它只包含一個不綁定到任何屬性的複選框,所以它有什麼意義!) – 2014-10-15 04:04:42

+0

如果你的示例使用了現有的擴展名,我表示歉意......我讀了超過曾經但顯然錯過了它。我可以發誓我是代碼只使用TagBuilder,你明確地添加屬性等。但我想我錯了。 – Jason 2014-10-15 13:19:20