ASP.Net MVC编辑模板,动态视图数据/表格 [英] ASP.Net MVC Editor template for dynamic view data / forms

查看:212
本文介绍了ASP.Net MVC编辑模板,动态视图数据/表格的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现检索某些用户的它的域可以从其他服务编辑这样的属性在视图中进行编辑的列表是在编译时完全动态的和未知的一个MVC3 /剃刀Web应用程序。

I am implementing a MVC3/Razor web application that retrieves some of its "fields" a user can edit from other services so the list of properties to edit in a view is completely dynamic and unknown at compile time.

我写了一些局部视图和HTML的助手说遍历组和属性从其他服务检索。现在,我在那里我必须建立针对各种物业类型的标签和点想为什么不能重新使用MVC编辑模板系统呢?有一个不同的数据类型的支持(如复选框等)和一个甚至与我的自定义模板自定义。

I wrote some partial-view and HTML-helpers that loop through the groups and properties retrieved from the other services. Now I am at the point where I have to build the tags for the various property types and thought why not re-use the MVC editor template system for this? There is support for various data-types (eg. checkboxes etc.) and one even customize them with my custom templates.

到目前为止好,但我该如何使用 Html.EditorFor() Html.Editor()的自定义的数据对象/属性?意为构建动态的形式而不静态类型数据的视图模型。

So far so good but how can I use Html.EditorFor() or Html.Editor() for custom data objects/properties? Meaning for building dynamic forms without static typed data as the view model.

下面是我的HTML帮助code的简约示例:

Here is a minimalistic sample of my HTML helper code:

public static MvcHtmlString GetField(this HtmlHelper helper, Field field)
{
...
   return helper.EditorFor(field, m => m.Value);
...
}

属性场是我从外部服务得到了现场。它有一个Object类型的值属性。我来样订做编辑code此属性类型。

The property "field" is the field I got from the external services. It has a "Value" property of type object. I like to build the editor code for this property-type.

据我所知,模板是建立在当前视图模型编辑器。我可以通过另一个对象的模型,则当前视图模型(如:在我上面的例子中的场)?

As I understand the editor templates are built on the current view model. Can I pass another object as the model then the current view model (eg. in my above example "field")?

任何帮助将是巨大的!

干杯,
马克

推荐答案

我的第一个ASP MVC任务涉及建立一个动态的形式,它是不是直线前进。结果
主要是因为他们期望强类型对象不能使用内置的佣工或验证。

My first ASP MVC task involved building a dynamic form, and it isn't straight forward.
Basically you can't use the built in helpers or validation because they expect strongly typed objects.

我的看法基本上是通过输入字段循环,检查数据类型(BOOL,INT,字符串,日期时间等),并直接建立一个编辑该类型。

My view basically loops through the input fields, checks the DataType (bool, int, string, datetime etc) and builds an editor directly for that type.

您也可以手动完成所有的验证,装饰类型的属性,这样做是不行的,看我的问题<一href=\"http://stackoverflow.com/questions/6304822/ifmodelstate-isvalid-doesnt-work-with-formscollection-what-to-use-instead\">if(ModelState.IsValid)不与FormsCollection工作。改用什么?

You also have to do all your validation manually, decorating the types with attributes to do this doesn't work, see my question if(ModelState.IsValid) doesn't work with FormsCollection. What to use instead?

的Razor视图逻辑(我们使用DevEx preSS MVC的扩展,但你的漂移)结果
窗体对象和它的Fields集合是我们的定制对象描述的形式应该是什么样子(页面收集标准搜索,这就是为什么你会看到标准,并在code搜索类型名称)。

Razor View logic (we use DevExpress MVC extensions, but you get the drift)
The form object and it's Fields collection are our bespoke objects that describe how the form should look (the page gathers criteria for searches, which is why you'll see criteria and search type names in the code).

<table id="criteriaTable">
@foreach (var field in form.Fields)
{
    <tr id="criteriaTableRow">
    @if (field.IsVisible)
    { 
    <td id="criteriaTableLabelCol"> 
       @Html.DevExpress().Label(s => s.Text = field.Caption).GetHtml()
    </td>
    <td id="criteriaTableEditCol">
        @if (field.Type == typeof(bool))
        {
           @Html.CheckBox(s =>
      {
          s.Checked = field.IsBoolSet;
          s.Name = field.Name;
          s.ClientEnabled = !field.IsReadonly;
      }).GetHtml()
        }
        else if (field.Type == typeof(DateTime))
        {
            Html.DevExpress().DateEdit(s =>
            {
                s.Name = field.Name;
                s.ClientEnabled = !field.IsReadonly;
                if (!string.IsNullOrEmpty(field.Value))
                {
                    DateTime dateValue;
                    if (DateTime.TryParse(field.Value, out dateValue))
                        s.Date = dateValue;
                }
            }).GetHtml();
        }
        else if (field.ListValues.Count > 0)
        {
            <input type="hidden" id="@("initiallySelected" + field.Name)" value="@field.Value" />
            Html.DevExpress().ListBox(s =>
            {
                s.Name = field.Name;
                s.ClientVisible = field.IsVisible;
                s.ClientEnabled = !field.IsReadonly;
                s.Properties.SelectionMode = DevExpress.Web.ASPxEditors.ListEditSelectionMode.CheckColumn;
                s.Properties.TextField = "Name";
                s.Properties.ValueField = "Value";
                s.Properties.ValueType = typeof(string);

                //s.Properties.EnableClientSideAPI = true;
                foreach (var item in field.ListValues)
                {
                    s.Properties.Items.Add(item.Name, item.Value);
                }

                //s.Properties.ClientSideEvents.SelectedIndexChanged = "MultiSelectListChanged";
                s.Properties.ClientSideEvents.Init = "MultiSelectListInit";
            }).GetHtml();

        }
        else
        {
            //Html.TextBox(field.Name, field.Value)
            Html.DevExpress().TextBox(s =>
            {
                s.Name = field.Name; s.Text = field.Value;
            }).GetHtml();
        }
        @Html.ValidationMessage(field.Name)
        <input type="hidden" name="@("oldvalue_" + field.Name)" value="@field.Value" />
        <input type="hidden" name="@("olduse_" + field.Name)" value="@(field.IncludeInSearch ? "C" : "U")" />
    </td>
    <td id="criteriaTableIncludeCol"> 
        @Html.DevExpress().CheckBox(s =>
   {
       s.Checked = field.IncludeInSearch;
       s.Name = "use_" + field.Name;
       s.ClientEnabled = (!field.IsMandatory);
   }).GetHtml()
    </td>
    }
    </tr>
}
    </table>

控制器动作接受一个窗体集合。通过formsCollection我环路寻找我在视图中指定的控件名称。

The Controller action accepts a Forms Collection. I loop through the formsCollection looking for the control names I specified in the view.

[HttpPost]
public ActionResult QueryCriteria(FormCollection formCollection)
{
    var isValid = true;
    foreach (var field in form.Fields)
    {
        var value = (formCollection[field.Name] ?? "").Trim();
        ...

如果有任何验证错误直接添加ModelError到模型例如我可以指定控制级验证

If there are any validation errors I can specify control level validation by adding a ModelError directly to the model e.g.

ModelState.AddModelError(field.Name, "This is a mandatory field");

和我返回查看是否有验证错误。

and I return the View if there are validation errors.

希望这有助于。

这篇关于ASP.Net MVC编辑模板,动态视图数据/表格的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆