如何将自定义DisplayTemplate与非文本字段一起使用,以便它不会覆盖现有值?

时间:2022-06-20 06:07:46

I've been following this guide on creating custom display attributes (specifically extra html attributes) to apply to the properties in my ViewModel. I have overridden both String and Boolean in the EditorTemplates folder. The editor template checks to see if a value has been set/the display attribute has been used - and adds the additional html attributes.

我一直在关注创建自定义显示属性(特别是额外的html属性)的指南,以应用于我的ViewModel中的属性。我在EditorTemplates文件夹中覆盖了String和Boolean。编辑器模板检查是否已设置值/已使用显示属性 - 并添加其他html属性。

I'm getting stuck on the Boolean override when performing an edit action though. Regardless of whether or not I apply the attribute to a string, the ViewModel always maps with the correct existing data. This isn't true with any other form input type, due to the way the templates have been written by changing the type attribute inside a TextBoxFor.

我在执行编辑操作时遇到了布尔覆盖。无论是否将属性应用于字符串,ViewModel始终使用正确的现有数据进行映射。由于通过更改TextBoxFor中的type属性来编写模板的方式,因此任何其他表单输入类型都不是这样。

I've been writing this primarily because I have been digging into knockout, and wanted an easy way to apply the data-bind attribute to strongly-typed views - if there's a better way please let me know!

我一直在写这个主要是因为我一直在挖掘淘汰赛,并想要一种简单的方法将数据绑定属性应用于强类型视图 - 如果有更好的方法请告诉我!

Attribute Code:

    public class Knockout : Attribute 
{
    public string DataBind { get; set; }
    public string InputType { get; set; }

    /*
    Example:
    Knockout("checked: showUploader", "checkbox")      
    Adds the HTML attributes data-bind="checked: showUploader" type="checkbox"
    */
    public Knockout(string dataBind, string inputType)
    {
        this.DataBind = dataBind;
        this.InputType = inputType;
    }
    public Dictionary<string, object> OptionalAttributes()
    {
        var options = new Dictionary<string, object>();

        if(!string.IsNullOrWhiteSpace(DataBind))
        {
            options.Add("data-bind", DataBind);
        }

        if (!string.IsNullOrWhiteSpace(InputType))
        {
            options.Add("type", InputType);
        }
        return options;
    }
}

Template Code

@using CumbriaMD.Infrastructure.ViewModels.DisplayAttributes
@{
   var key = "Knockout";
}

@if (ViewData.ModelMetadata.AdditionalValues.ContainsKey(key))
{
   var knockout = ViewData.ModelMetadata.AdditionalValues[key] as Knockout;
   @Html.TextBoxFor(model => model, knockout.OptionalAttributes())
}
else
{

/*
When the attribute is not present, the default action is the following - which seems to
be overriding the data mapped from the database:
*/
    @Html.TextBoxFor(model => model, new { type="checkbox" })
}

1 个解决方案

#1


0  

Found the answer nested in this beauty of a question!

找到了这个美丽问题的答案!

My working template for boolean values now looks like:

我的布尔值工作模板现在看起来像:

@using CumbriaMD.Infrastructure.ViewModels.DisplayAttributes
@{
   var key = "Knockout";
   bool? value = null;
   if(ViewData.Model != null)
   {
      value = Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
   }
}

@if (ViewData.ModelMetadata.AdditionalValues.ContainsKey(key))
{
   var knockout = ViewData.ModelMetadata.AdditionalValues[key] as Knockout;
   @Html.CheckBox("", value ?? false, knockout.OptionalAttributes())
}
else
{
   @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}

#1


0  

Found the answer nested in this beauty of a question!

找到了这个美丽问题的答案!

My working template for boolean values now looks like:

我的布尔值工作模板现在看起来像:

@using CumbriaMD.Infrastructure.ViewModels.DisplayAttributes
@{
   var key = "Knockout";
   bool? value = null;
   if(ViewData.Model != null)
   {
      value = Convert.ToBoolean(ViewData.Model, System.Globalization.CultureInfo.InvariantCulture);
   }
}

@if (ViewData.ModelMetadata.AdditionalValues.ContainsKey(key))
{
   var knockout = ViewData.ModelMetadata.AdditionalValues[key] as Knockout;
   @Html.CheckBox("", value ?? false, knockout.OptionalAttributes())
}
else
{
   @Html.CheckBox("", value ?? false, new { @class = "check-box" })
}