复选框的自定义助手不绑定
custom helper for checkbox not binding
当使用 html 助手 CheckBoxFor() 时,可以这样做:
@Html.CheckBoxFor(model => model.active)
这将导致 html 代码如下:
<input class="check-box" id="active" name="active" type="checkbox" value="true" />
<input name="active" type="hidden" value="false" />
我的问题是,我正在使用的 html/css 模板需要在复选框字段之后添加一个特定的标签才能工作。 (复选框上的某些 css/jquery 效果需要它)。所以我需要修改 CheckBoxFor() 来生成这个:
<input class="check-box" id="active" name="active" type="checkbox" value="true" />
<i class="no-rounded"></i>
<input name="active" type="hidden" value="false" />
我试过像这样创建自定义扩展方法:
public static MvcHtmlString CustomCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string propertyName = data.PropertyName;
string s = "";
s += "<input class=\"check-box\" id=\"" + propertyName + "\" name=\"" + propertyName+ "\" type=\"checkbox\" value=\"true\" />";
s += "<i class=\"no-rounded\"></i>";
s += "<input name=\"" + propertyName + "\" type=\"hidden\" value=\"false\" />";
return MvcHtmlString.Create(s.ToString());
并用
调用它
@Html.CustomCheckboxFor(model => model.active)
这正在绘制复选框,并且 css/jquery 效果正常,
但 在创建或编辑视图时,它没有绑定到模型上的 属性 (如果 属性 为真,它应该加载表单复选框已选中,但没有)
我该怎么做?
更新:
好的,我取得了一些进步,它现在可以工作了,但我敢打赌一定有更好、更优雅的方法来做到这一点……我所做的是让 .net 助手完成生成 html 的工作复选框和隐藏字段的代码。然后我得到了那个字符串,然后在两个字段之间插入所需的标签,return 那:
public static MvcHtmlString UnifyCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
string s = helper.CheckBoxFor(expression).ToString();
string part1 = s.Substring(0,s.IndexOf(">")+1);
string part2 = s.Substring(s.IndexOf(">")+1);
string str = part1 + "<i class=\"no-rounded\"></i>" + part2;
return MvcHtmlString.Create(str.ToString());
}
UPDATE2:@Joshua Duxbury 在评论中给出的信息:如果创建自定义助手,框架不会尝试绑定它,所以我们必须自己在帮手。所以初始代码只需添加该逻辑即可工作:
public static MvcHtmlString CustomCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string propertyName = data.PropertyName;
string s = "";
s += "<input class=\"check-box\" id=\"" + propertyName + "\" name=\"" + propertyName+ "\" type=\"checkbox\" value=\"true\" " + ((data.Model.Equals(true)) ? "checked=\"checked\"" : "") +"/>";
s += "<i class=\"no-rounded\"></i>";
s += "<input name=\"" + propertyName + "\" type=\"hidden\" value=\"false\" />";
return MvcHtmlString.Create(s.ToString());
}
修正
正如我们在 OP 评论中所讨论的,您需要在 HTML 助手中设置复选框的值。写复选框HTML代码时写checked=checked
部分
Your hard coding value="true"
on the input tags, shouldn't this be set
based on the model property?
备选方案
像这样在扩展方法中手动创建 HTML 并不是最佳做法,您将忽略扩展方法提供的所有功能
- 2 向模型绑定不正确
- 模型状态验证
- 不呈现
data-val
属性
因此,如果您需要做的只是在 HTML 标记后插入一些 HTML,您可以使用脚本语言在客户端执行此操作。下面的例子写在jQuery.
jQuery 例子
$("<i class=\"no-rounded\"></i>").insertAfter("input .check-box");
当使用 html 助手 CheckBoxFor() 时,可以这样做:
@Html.CheckBoxFor(model => model.active)
这将导致 html 代码如下:
<input class="check-box" id="active" name="active" type="checkbox" value="true" />
<input name="active" type="hidden" value="false" />
我的问题是,我正在使用的 html/css 模板需要在复选框字段之后添加一个特定的标签才能工作。 (复选框上的某些 css/jquery 效果需要它)。所以我需要修改 CheckBoxFor() 来生成这个:
<input class="check-box" id="active" name="active" type="checkbox" value="true" />
<i class="no-rounded"></i>
<input name="active" type="hidden" value="false" />
我试过像这样创建自定义扩展方法:
public static MvcHtmlString CustomCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string propertyName = data.PropertyName;
string s = "";
s += "<input class=\"check-box\" id=\"" + propertyName + "\" name=\"" + propertyName+ "\" type=\"checkbox\" value=\"true\" />";
s += "<i class=\"no-rounded\"></i>";
s += "<input name=\"" + propertyName + "\" type=\"hidden\" value=\"false\" />";
return MvcHtmlString.Create(s.ToString());
并用
调用它@Html.CustomCheckboxFor(model => model.active)
这正在绘制复选框,并且 css/jquery 效果正常, 但 在创建或编辑视图时,它没有绑定到模型上的 属性 (如果 属性 为真,它应该加载表单复选框已选中,但没有)
我该怎么做?
更新: 好的,我取得了一些进步,它现在可以工作了,但我敢打赌一定有更好、更优雅的方法来做到这一点……我所做的是让 .net 助手完成生成 html 的工作复选框和隐藏字段的代码。然后我得到了那个字符串,然后在两个字段之间插入所需的标签,return 那:
public static MvcHtmlString UnifyCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
string s = helper.CheckBoxFor(expression).ToString();
string part1 = s.Substring(0,s.IndexOf(">")+1);
string part2 = s.Substring(s.IndexOf(">")+1);
string str = part1 + "<i class=\"no-rounded\"></i>" + part2;
return MvcHtmlString.Create(str.ToString());
}
UPDATE2:@Joshua Duxbury 在评论中给出的信息:如果创建自定义助手,框架不会尝试绑定它,所以我们必须自己在帮手。所以初始代码只需添加该逻辑即可工作:
public static MvcHtmlString CustomCheckboxFor<TModel>(this HtmlHelper<TModel> helper, Expression<Func<TModel, bool>> expression)
{
var data = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
string propertyName = data.PropertyName;
string s = "";
s += "<input class=\"check-box\" id=\"" + propertyName + "\" name=\"" + propertyName+ "\" type=\"checkbox\" value=\"true\" " + ((data.Model.Equals(true)) ? "checked=\"checked\"" : "") +"/>";
s += "<i class=\"no-rounded\"></i>";
s += "<input name=\"" + propertyName + "\" type=\"hidden\" value=\"false\" />";
return MvcHtmlString.Create(s.ToString());
}
修正
正如我们在 OP 评论中所讨论的,您需要在 HTML 助手中设置复选框的值。写复选框HTML代码时写checked=checked
部分
Your hard coding
value="true"
on the input tags, shouldn't this be set based on the model property?
备选方案
像这样在扩展方法中手动创建 HTML 并不是最佳做法,您将忽略扩展方法提供的所有功能
- 2 向模型绑定不正确
- 模型状态验证
- 不呈现
data-val
属性
因此,如果您需要做的只是在 HTML 标记后插入一些 HTML,您可以使用脚本语言在客户端执行此操作。下面的例子写在jQuery.
jQuery 例子
$("<i class=\"no-rounded\"></i>").insertAfter("input .check-box");