简体   繁体   English

ASP.NET MVC - 将外部模型传递给编辑器模板

[英]ASP.NET MVC - Pass outer model to editor template

I'm using custom editor templates for most of my forms, but while attempting to use them to render a custom object picker I've found no easy way to pass information about the containing context to the editor template. 我正在为大多数表单使用自定义编辑器模板,但在尝试使用它们呈现自定义对象选择器时,我发现没有简单的方法将有关包含上下文的信息传递给编辑器模板。

Specifically, my main form renders an edit for a domain object, and the editor template needs to render an AJAX picker which contains a list of objects which are dependent on the ID of the domain object. 具体来说,我的主窗体呈现域对象的编辑,编辑器模板需要呈现一个AJAX选择器,其中包含依赖于域对象ID的对象列表。 I'm passing the ID using the additionalViewData parameter currently, which I think is error prone and therefore quite ugly. 我正在使用当前的additionalViewData参数传递ID,我认为这很容易出错,因此非常难看。

My form contains code similar to the following: 我的表单包含类似于以下内容的代码:

@Html.EditorFor(model => model.CategoryId, new { id = model.id })

The editor template contains code like the following: 编辑器模板包含如下代码:

@{
var domainObjectId = ViewData["id"] as int?;
}

I'm using a custom ModelMetadataProvider to select the object picker editor template, and hope to use a similar technique to pass information about the containing model to the editor template, but that doesn't seem be possible. 我正在使用自定义的ModelMetadataProvider来选择对象选择器编辑器模板,并希望使用类似的技术将有关包含模型的信息传递给编辑器模板,但这似乎是不可能的。

So, my questions are: 所以,我的问题是:

  1. Is there anyway to use a ModelMetadataProvider to pass information about the containing model to the editor template? 无论如何使用ModelMetadataProvider将有关包含模型的信息传递给编辑器模板?
  2. If not, is there any neater/easier way to achieve what I'm attempting, aside from passing every piece of additional information via the weakly typed additionalViewData parameter? 如果没有,除了通过弱类型的additionalViewData参数传递每一条附加信息之外,还有更简洁/更简单的方法来实现我正在尝试的东西吗?

Thanks in advance! 提前致谢!

You need to understand that EditorTemplates are designed to be type specific, not context specific. 您需要了解EditorTemplates被设计为特定于类型,而不是特定于上下文。 Some thought was given to this with the AdditionalViewData parameter, but that's the best you're going to get. 使用AdditionalViewData参数给出了一些想法,但这是你将获得的最好的。

If you're concerned about type safety, use ViewBag instead, which is a type-safe dynamic wrapper around ViewData. 如果您担心类型安全,请使用ViewBag,这是一个围绕ViewData的类型安全的动态包装器。

@{
    var domainObjectId = ViewBag.Id;
}

I wonder if maybe the controller that is creating this view model in the first place should be the thing that chooses the list of objects. 我想知道是否可能首先创建此视图模型的控制器应该是选择对象列表的东西。 So rather than having an integer property on your view model, you could have a sub property of another type of view model, ie: 因此,您可以拥有另一种视图模型的子属性,而不是在视图模型上具有整数属性,即:

public class OuterViewModel
{
    public CategoryViewModel Category { get; set; }
}

public class CategoryViewModel
{
    public int CategoryId { get; set; }

    public IEnumerable<SelectListItem> ListOfThings { get; set; }
}

Then your original view can just have: 然后你的原始视图可以有:

@Html.EditorFor(model => model.Category)

With an EditorTemplate for CategoryViewModel that looks like: 使用适用于CategoryViewModel的EditorTemplate,如下所示:

@model CategoryViewModel
@Html.DropDownFor(m => m.CategoryId, Model.ListOfThings)

The only thing you have to remember this is if you do any server side business logic validation, add model errors and return to your view you will need to re populate your list of things in your controller post action. 您唯一需要记住的是,如果您执行任何服务器端业务逻辑验证,添加模型错误并返回到您的视图,则需要重新填充控制器后期操作中的事项列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM