ASP.NET MVC - 更好的UX的方法来让孩子对象编辑比循环和局部视图 [英] ASP.NET MVC - Better UX approach to allowing child object editing than For loop and Partial Views

查看:126
本文介绍了ASP.NET MVC - 更好的UX的方法来让孩子对象编辑比循环和局部视图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有许多特性,其中包括一名儿童是地址列表的联系对象。

 公共类联系
{
  公众诠释?标识{搞定;组; }
  公共字符串名称{;组; }
  公共IReadOnlyList< IAddress>地址
  {
      [延迟加载code填充并返回列表]
  }
  [...]
}

欲允许用户不必编辑(或交)的全部联系人对象编辑中的地址。目前在UI我有与编辑按钮罗列出来的地址,接下来的每个人:

我使用的模态语法,Bootstrap3的一部分,都隐藏着含有一种形式,要修改地址字段的DIV。当用户点击编辑,一个模式窗口形式出现,允许用户编辑地址。这种形式在模型绑定和验证工作。

它的工作原理pretty很好,但我有实施的几个根本问题。我想利用内置的验证和模型地址绑定的对象,但我不想回发整个对象只需编辑一个地址。

所以,我最后不得不创建一个for循环,写出了隐藏层调用的局部视图,并通过地址为模型:

  @for(INT I = 0; I< Model.Addresses.Count;我++)
{
        地址=(地址)Model.Addresses [I]
        @ Html.Partial(_ AddressModal,地址);
}

不幸的副作用是,该模型结合不能唯一标识地址的ModelState申请,所以模型绑定它适用于所有的地址在隐藏层,而不是一个已更新。这是因为他们有相同的属性名。

我有一个变通办法,这是一个较早前的问题的一部分。基本上,除非对象是无效的不写的ModelState。为无效的情况下,我不显示它基本上隐藏问题的地址列表。否则,每一个编辑按钮会显示同样形式的内容。

我想知道的是,如果有更好的UX的方法来允许用户编辑列表中孩子的地址吗?

我的目标是找到使用ASP.NET MVC更好的方法是:


  1. 按照PRG(后重定向-GET)模式

  2. 请不要重定向到一个单独的页面/视图进行编辑,这迫使用户导航返回到联系人编辑表单再次

  3. 避免因为阻滞剂弹出窗口

  4. 该解决方案允许使用模式绑定和验证的地址对象


解决方案

你想要的是:

1表格的接触
另一种形式为每个地址

在你的控制器,你将有希望的联系人作为参数(无地址)的行动,并希望地址其他操作。

样板code:

  [HttpPost]
    公共RedirectToRouteResult EditAddress(INT ID,ContactAddressBindingModel地址){
        // ...
    }    [HttpPost]
    公共RedirectToRouteResult EditContact(INT ID,ContactBindingModel联系)
    {
        // ...
    }    公共类ContactViewModel:ContactBindingModel
    {
        公共IReadOnlyList< IAddress>地址{// ...}
    }
    公共类ContactBindingModel
    {
        公众诠释?标识{搞定;组; }
        公共字符串名称{;组; }
    }
    公共类ContactAddressBindingModel:IAddress
    {
        公众诠释?标识{搞定;组; }
        公共字符串城{搞定;组; }
        公共字符串国家{搞定;组; }    }

和视图:

 <形式的行动=EditContact>
<! - 触点输入等等 - >
< /表及GT;//在剃须刀,你可以做EditorFor(M = GT; m.Addresses)代替的foreach
//并有partialview,或任何你喜欢。@foreach(Model.Addresses){
<形式的行动=EditAddress>
<! - 地址输入等 - >
< /表及GT;
}

I have a Contact object that has a number properties, including a child that is a list of Addresses.

public class Contact
{ 
  public int? Id { get; set; }
  public string Name { get; set; }
  public IReadOnlyList<IAddress> Addresses
  {
      [Lazy Load Code to populate and return list]
  } 
  [...]
}

I want to allow the user to edit the addresses without having to edit (or post) the whole Contact object. Currently in the UI I have the addresses listed out with an Edit button next each one:

I'm using the Modal syntax that is part of Bootstrap3, and have hidden DIVs that contain a form and the fields to edit an Address. When the user clicks on edit, a modal window form appears that allows the user to edit the Address. Model Binding and validation work within this form.

It works pretty well but I have a few underlying issues with the implementation. I wanted to use the builtin Validation and Model Binding with the Address objects, but I didn't want to post back the whole object just to edit one address.

So I ended up having to create a for loop that writes out the hidden DIVs calling a Partial View and passing Address as the model:

@for (int i = 0; i < Model.Addresses.Count; i++)
{
        address = (Address)Model.Addresses[i];
        @Html.Partial("_AddressModal", address);
}

The unfortunate side-effect is that the model binding cannot uniquely identify which Address to apply the ModelState to, so Model Binding applies it to all the Address in in the hidden DIVs, instead of the one that was updated. This is because they have the exact same property names.

I've got a work-around that was part of an earlier question. Basically it doesn't write the ModelState unless the object is invalid. For the invalid scenario I don't show the address list which basically hides the problem. Otherwise every edit button would show the same form content.

What I want to know is if there is a better UX approach to allow a user to edit one of the child Addresses in the list?

My goals are to find a better approach using ASP.NET MVC that:

  1. Follow the PRG (Post-Redirect-Get) pattern
  2. Don't redirect to a separate Page/View for editing, which forces the user to navigate back to the contact edit form again
  3. Avoid popups because of the blockers
  4. The solution allows the use Model Binding and Validation for the Address object

解决方案

What you want is :

1 Form for the contact Another form for each address

in your controller you will have an action that expects a contact as a parameter (without addresses) and another action that expects an address.

boilerplate code:

    [HttpPost]
    public RedirectToRouteResult EditAddress(int id, ContactAddressBindingModel address) {
        // ...
    }

    [HttpPost]
    public RedirectToRouteResult EditContact(int id, ContactBindingModel contact)
    {
        // ...
    }

    public class ContactViewModel : ContactBindingModel
    {
        public IReadOnlyList<IAddress> Addresses { // ...}
    }
    public class ContactBindingModel
    {
        public int? Id { get; set; }
        public string Name { get; set; }
    }
    public class ContactAddressBindingModel : IAddress
    {
        public int? Id { get; set; }
        public string City { get; set; }
        public string Country { get; set; }

    }

and in the view :

<form action="EditContact">
<!-- contacts inputs etc -->
</form>

// in razor you can do EditorFor(m => m.Addresses) instead of foreach
// and have partialview, or whatever you like.

@foreach (Model.Addresses) { 
<form action="EditAddress">
<!-- address inputs etc -->
</form>
}

这篇关于ASP.NET MVC - 更好的UX的方法来让孩子对象编辑比循环和局部视图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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