从MVC5中的EditorTemplates提交复杂数据的正确方法

时间:2015-06-19 17:20:34

标签: ajax asp.net-mvc-5

我正在使用我的UserProfile编辑器,我正在使用EditorTemplates,但我无法找到使用此方法为复杂对象提交数据的正确方法。我不知道我是否有正确的视图,以及如何从所有部分视图中汇总复杂对象。为了简化,我将稍微减少一点,但我的UserProfile有许多表示用户首选项的子对象。

CREATE TABLE [dbo].[UserProfile] (
    [UserProfileId]     INT           IDENTITY (1, 1) NOT NULL,
    [NickName]          VARCHAR (MAX) NOT NULL,
    [ThumbnailImageId]  INT           NULL,
);

在我的实体中,我有导航对象指向ThumbnailImage对象,因此在我的EditorTemplate(对于UserProfile)中,我可以这样做:

<div class="form-group">
    @Html.LabelFor(model => model.NickName, htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.NickName, new { htmlAttributes = new { @class = "form-control" } })
</div>

<div class="form-group">
    @Html.LabelFor(model => model.ThumbnailImage, "ThumbnailImage", htmlAttributes: new { @class = "control-label col-md-2" })
    @Html.EditorFor(model => model.ThumbnailImage, new { @class = "form-control" })
</div>

请注意,第二个EditorFor是ThumbnailImage对象,而不是ID。我有一个EditorTemplate用于该对象,但我不确定哪种编码方式最好。我知道怎么做,我只是想找哪种方式来挑选。如果有“最佳实践”,请告诉我。

选项1 - “手动”汇总UserProfile视图中的顶级对象。对于此选项,我将在UserProfile视图中进行Ajax调用,该视图提交整个对象,包括ThumbnailImageId,它将使用JQuery使用HTML元素ID的前缀从ThumbnailImage编辑器中获取。因此,我的提交按钮将存在于UserProfile EditorTemplate中,其操作将如下所示...(除了将生成URL和元素ID)

var NickName = $('#MyNickNameId').val();
var ThumbnailImageId = $('#ImageEditorId').val();
$.ajax({
     url: '/Account/UserProfile',
     contentType: 'application/html; charset=utf-8',
     data: {
        UserProfileId: idVal, 
        NickName: NickName,
        ThumbnailImageId: ThumbnailImageId 
     }
 });

选项2 - 立即编辑子对象,不要在顶级视图中提交它们。在此选项中,我的ThumbnailImage编辑器将使用Ajax立即更新数据库,方法是保存图像数据本身,然后使用ID更新父对象(如果已更改)。这样,当用户提交顶级UserProfile编辑器时,它只会提交NickName,并且对子对象的任何更新都已经完成。我喜欢这个选项以获得流畅的UI原因,但我也可以让选项1对用户来说也很流畅。

选项3 - 取消子对象的EditorTemplates(ThumbnailImage)并在父(UserProfile)视图中编辑它们 - 这意味着我会在视图中有重复的代码,因为其他事物将有ThumbnailImage对象,而不仅仅是用户配置文件。将整个对象放在一个视图中有点简单,但我没有看到任何优势(但是,这是我们在工作中所做的,我们不使用模型绑定)

我如何找出合适的选项,或者我没有考虑更好的选择?

目前我正在做选项1.它可以工作,但它是很多代码而且不是很容易重复使用。

1 个答案:

答案 0 :(得分:0)

我不知道你的设置是如何工作既不理解C#的东西。但是,这是一个标准的做法,受到目前由面向对象设计,Scala的Akka框架,Ember.js的多个组件等使用的Erlang演员的欢迎。

想象一下以数据为中心的树。有一个根节点。每个节点都有子节点和一个父节点。

现在想象一下对象树。有一个名为supervisor的根对象。每个节点都有一个名为workers的子节点和一个称为其主管的父节点。每个节点都监督其所有孩子。

监督的定义是确保受监督的演员或更一般的术语对象处于可接受的状态。可以获取请求,处理它们并回复。例如,在例外情况下,主管可以选择重新初始化受监督的演员。

在这样的系统中,root获取最抽象的消息,比如getCredentials,负责构建worker,拆分任务并跟踪本地状态。

自然root创建一个表单。作为root的孩子的表单创建了两个负责处理<input>标签的演员和一个负责发送提交的演员。

当提交者告诉其父母,表格时,它应该提交。表单会询问每个输入的值,从中构建一个dict / hash并使用该数据回复root。

现在root负责将此数据发送到服务器。这样,逻辑,数据,状态和行为就可以保留在大多数本地。