2012-12-25 96 views
0

有沒有辦法將視圖模型傳遞給@helper函數?從剃刀幫手中進入模型

我有一個顯示Yes/No/Maybe單選按鈕的自定義編輯器。這個編輯器的代碼如下所示。因爲它需要一個自定義的函數加上代碼,以顯示每個單選按鈕3條線,我想封裝用於創建每個單選按鈕,並在全球@helper功能及其相關聯的標籤代碼,但我無法弄清楚如何將RadioButtonFor移動到全局幫助函數中。

鮑勃

這是現有代碼:

@model System.String 

@functions { 
    // Returns an anonymous object that specifies the radio button HTML options 
    private object HTMLOptions(string id, bool @checked) { 
     if (@checked) { 
      return new { id, @checked = "checked" }; 
     } else { 
      return new { id }; 
     } 
    } 
} 

@{ 
    string value = Model + ""; 
    string id; 
} 

<div class="option-list"> 
    @{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioYes");} 
    @Html.RadioButtonFor(q => q, "true", HTMLOptions(id, value == "true")) 
    @Html.LabelFor(q => q, "Yes", new {@for = id}) 
    <br /> 

    @{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioNo");} 
    @Html.RadioButtonFor(q => q, "false", HTMLOptions(id, value == "false")) 
    @Html.LabelFor(q => q, "No", new {@for = id}) 
    <br /> 

    @{id = ViewData.TemplateInfo.GetFullHtmlFieldId("radioMaybe");} 
    @Html.RadioButtonFor(q => q, "maybe", HTMLOptions(id, value == "maybe")) 
    @Html.LabelFor(q => q, "Maybe", new {@for = id}) 
    <br /> 
</div> 

我希望能夠寫一個通用的幫手,它封裝RadioButtonFor和LabelFor,再加上我的額外代碼,包括「檢查」屬性,在一個呼叫,像這樣:

@model something 

<div class="option-list"> 
    @MyRadioButtonAndLabelFor(q => something.x, "Yes", "true") @* (model, label, value) *@ 
    @MyRadioButtonAndLabelFor(q => something.x, "No", "false") 
    @MyRadioButtonAndLabelFor(q => something.x, "Maybe", "maybe") 
</div> 

回答

2

嘗試這樣的:

@model System.String 

@functions { 
    private object HtmlAttributes(string id, string model, string value) { 
     if (model == value) { 
      return new { id, @checked = "checked" }; 
     } 

     return new { id }; 
    } 
} 

@helper Radios(HtmlHelper<string> html) { 
    var model = html.ViewData.Model; 

    @html.RadioButtonFor(q => q, "true", HtmlAttributes("yes", model, "true")) 
    @Html.LabelFor(q => q, "Yes", new { @for = "yes" }) 
    <br/> 

    @html.RadioButtonFor(q => q, "false", HtmlAttributes("no", model, "false")) 
    @Html.LabelFor(q => q, "No", new { @for = "no" }) 
    <br/> 

    @html.RadioButtonFor(q => q, "maybe", HtmlAttributes("maybe", model, "maybe")) 
    @Html.LabelFor(q => q, "Maybe", new { @for = "maybe" }) 
    <br/> 
} 

<div class="option-list"> 
    @Radios(Html) 
</div> 


UPDATE:

看來,我看錯你的問題。更新後,我更瞭解你正在努力實現的目標。爲了實現它,你可以寫一個自定義的HTML幫助:

using System; 
using System.Linq.Expressions; 
using System.Text; 
using System.Web; 
using System.Web.Mvc; 
using System.Web.Mvc.Html; 

public static class HtmlExtensions 
{ 
    public static IHtmlString MyRadioButtonAndLabelFor<TModel, TValue>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TValue>> expression, 
     string label, 
     object value 
    ) 
    { 
     var name = ExpressionHelper.GetExpressionText(expression); 
     var id = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(
      name + value 
     ); 
     var sb = new StringBuilder(); 
     sb.Append(htmlHelper.RadioButtonFor(expression, value, new { id = id })); 
     var labelTag = new TagBuilder("label"); 
     labelTag.SetInnerText(label); 
     labelTag.Attributes["for"] = id; 
     sb.Append(labelTag.ToString()); 
     return new HtmlString(sb.ToString()); 
    } 
} 

,然後你可以有一個視圖模型:

public class MyViewModel 
{ 
    public string Value { get; set; } 
} 

控制器:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      Value = "false" 
     }); 
    } 
} 

和相應的視圖:

@model MyViewModel 

<div class="option-list"> 
    @Html.MyRadioButtonAndLabelFor(q => q.Value, "Yes", "true") 
    @Html.MyRadioButtonAndLabelFor(q => q.Value, "No", "false") 
    @Html.MyRadioButtonAndLabelFor(q => q.Value, "Maybe", "maybe") 
</div> 

備註:在在範圍帶來秩序的MyRadioButtonAndLabelFor自定義擴展方法,你需要添加在其包含的類(HtmlExtensions)已經聲明爲在命名空間標籤的命名空間的~/Views/web.config(不~/web.config)或視圖本身通過增加內@using ...指令。


,如果你願意的話,還可以定義你的Razor視圖裏面的助手在線:

@functions { 
    public IHtmlString MyRadioButtonAndLabelFor<TModel, TValue>(
     HtmlHelper<TModel> htmlHelper, 
     System.Linq.Expressions.Expression<Func<TModel, TValue>> expression, 
     string label, 
     object value 
    ) 
    { 
     var name = ExpressionHelper.GetExpressionText(expression); 
     var id = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(name + value); 

     var sb = new StringBuilder(); 
     sb.Append(htmlHelper.RadioButtonFor(expression, value, new { id = id })); 
     var labelTag = new TagBuilder("label"); 
     labelTag.SetInnerText(label); 
     labelTag.Attributes["for"] = id; 
     sb.Append(labelTag.ToString()); 

     return new HtmlString(sb.ToString()); 
    } 
} 

,然後用它是這樣的:

<div class="option-list"> 
    @MyRadioButtonAndLabelFor(Html, q => q.Value, "Yes", "true") 
    @MyRadioButtonAndLabelFor(Html, q => q.Value, "No", "false") 
    @MyRadioButtonAndLabelFor(Html, q => q.Value, "Maybe", "maybe") 
</div> 

至於剃刀幫手關注(@helper定義),好吧,它們不能是通用的,因此你會遇到麻煩,聲明這樣的結構。

+0

感謝Darin。我想我的問題並不清楚。我已經更新了更具體的問題。 –

+0

@ Bob.at.SBS,在更新之後,它更清晰地表達你的想法。我已經用我的答案更新了一個如何實現這個目標的例子。 –