2016-03-14 10 views
5

私は経験豊富な.NET C#ソフトウェア開発者ですが、ほんの数ヶ月前にMVC Razor(MVC 5)で作業を開始しました。MVC Razorは、提出するオブジェクトのリストを作成します。

私は順番にものリストを持っている他のモデルのリストを持っているモデルを持っている私は(検索の時間後)の純

上への答えを見つけることができませんでした小さな状況があります次のようなモデルです。

public class Parent 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
    public List<Child> Children { get; set; } 
} 

public class Child 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
    public List<GrandChild> GrandChildren { get; set; } 
} 

public class GrandChild 
{ 
    public string Name { get; set; } 
    public string Sex { get; set; } 
    public int Age { get; set; } 
} 

と私のコントローラは、1つの取得のメインである、2つの方法があり、他の一つはしかし、フォームでの私の見解では、私は方法を見つけることができない新しいデータ

public ActionResult Index() 
{ 
    return View(); 
} 

[HttpPost] 
public ActionResult PostParent(Parent parent) 
{ 
    if (ModelState.IsValid) 
    { 
     //Do an insert to the DB 
     return View("~/Views/Home/Index.cshtml"); 
    } 

    return Json("Error"); 
} 

を投稿するためにポストであります(子供の包み)追加ボタンを作成し、子供や孫のリストに新しいデータを挿入する

@using (Html.BeginForm("PostParent", "Home", FormMethod.Post, new {@class = "form-horizontal", role = "form"})) 
{ 
    @Html.LabelFor(x => x.Name) 
    @Html.TextBoxFor(x => x.Name) 
} 

私は唯一のプリミティブ型properitesのためではなく、オブジェクトのフィールドを追加することができます。

本当にありがとうございました!

+0

答え[ここ](http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796#29161796)と[ここ](http://stackoverflow.com)を参照してください。/questions/28019793/submit-same-partial-view-multiple-times-data-to-controller/28081308#28081308)。ネストされたコレクションに 'BeginCollectionItem'を使用できないことに注意してください。 –

+0

ネストされたコレクションを動的に作成する実際の例については、[こちらのDotNetFiddle](https://dotnetfiddle.net/wqE6Rb) –

答えて

2

私はあなたがHTML5から知っておくべき通常の標準<input/>が必要だと思います。 私が正しく理解していれば、ビューからコントローラにデータを渡したいと思っています。これで、作成したフォームにボタンが必要になります。 モデルデータをビューからコントローラに渡すことによって、コントローラを呼び出す必要がある/必要があります。

@Html.ActionLink("Click here to pass", "ActionName", new { ParameterNameOfTheController = Model }) 

その原料の背後にあるロジックはコントローラーで起こるべき:@Html.ActionLink()<Input>

用カミソリヘルパーでフォーム内でこのような何かはトリックを行う必要があります。 これがあなたを助けてくれることを願っています。

+0

こんにちはH. Senkaya はい、サブミットボタンを押して、ロジックがコントローラにありますが、新しいリストを作成し、ビューからリストに項目を追加する方法が不思議です。サブミットをクリックすると、データがそこに表示されます。 –

2

あなたのシナリオに関連するプロジェクトを行いました。しかし、私はかみそりの解決策を見つけることができませんでした。そこで私はSheepIt jqueryプラグインを使ってフィールドを動的に追加しました。

https://github.com/mdelrosso/sheepit

あなたはidとのASP MVCは理解名前のパターンに固執することを確認してください。

<input class="form-control text-box single-line" id="sheepItForm_#index#__Field" name="sheepItForm[#index#].Field" type="text" value="" /> 
 
<span class="field-validation-valid text-danger" data-valmsg-for="sheepItForm[0].Field" data-valmsg-replace="true"></span>

この情報がお役に立てば幸い!

あなたは何ができるか Html.BeginCollectionItem https://www.nuget.org/packages/BeginCollectionItem/

を使用することができます。このため

+0

こんにちはVish J 私は実際に純粋なjavascriptを使用して項目をリストに追加し、mvc命名パターンに固執して解決策を見つけました。しかし、複雑なネストされたオブジェクトがあれば、時間がかかります。 –

7

は、メインフォームのビューを持っており、これは親を代表するとしてそれにParentモデルを渡し、その後、あなたが必要になりますですあなたはこれを呼び出すことができますChildRow.cshtml

私たちが作成している親のためCreate.cshtml親モデルを渡すビュー。

@model Parent 

@using(Html.BeginForm()) 
{ 
    @Html.TextBoxFor(m => m.Name) 


    <table id="children"> 
     <tbody> 

<!-- This here will display the Child Row for existing Rows in the Parent model --> 

      @foreach (var child in Model.Children) 
      { 
       @Html.Partial("ChildRow", child) 
      } 
     </tbody> 

    </table> 
<button type="button" id="addChild">Add Child</button> 

<button type="submit"> Save</button> 
    } 

は、次に、このChildRow.cshtmlは、次のようになりますそれはChildモデルを持つことになりますものです。

注:子モデルにIsDeletedプロパティを追加する必要があります。これは、コントローラで子どもが削除されたかどうかを確認するのに役立ちます。

@model Child 

@using (Html.BeginCollectionItem("Children")) 
{ 
    <tr> 
     <td> 
      @Html.HiddenFor(m => m.IsDeleted, new { data_is_deleted = "false" }) 
      @Html.HiddenFor(m => m.ChildId) 
      @Html.TextBoxFor(m => m.Name) 
     </td> 

     <td> 
      <span class="glyphicon glyphicon-trash action-icon" data-action="removeItem"></span> 
     </td> 


    <tr> 
} 

今、あなたはボタンAdd Childがクリックされたときに、表の最後に行を追加する必要があります。

このためには、コントローラで新しいアクションを作成します:表に新しい子行を追加しますCreate.cshtml

$("#addChild").on("click", function() { 
     $.ajax({ 
      url: '@Url.Action("AddChild", "YourController")' 
     }).success(function (partialView) { 
      $('#children> tbody:last-child').append(partialView); 
     }); 
    }); 

これには、このjQueryのを追加し

public ActionResult AddChild() 
    { 
     return PartialView("Child", new Child()); 
    } 

をそして

また、同じページでも削除したい場合は、行を非表示/無効にする必要があります。そのためには、このjQueryを追加できます。

$('body').on("click", '*[data-action="removeItem"]', function (e) { 
    e.stopPropagation(); 
    var btn = $(this); 
    var row = btn.closest('tr'); 
    var firstCell = $(row.find('td')[0]); 
    var checkBox = firstCell.find('*[data-is-deleted]'); 
    var checkBoxVal = checkBox.val(); 

    if (checkBoxVal === 'False' || checkBox.val() === 'false') { 
     checkBox.val('true'); 
     row.find('td').find('input, textarea, select').attr('readonly', 'readonly'); 
    } else { 
     checkBox.val('false'); 
     row.find('td').find('input, textarea, select').attr("readonly", false); 
    } 

}); 

コントローラにPOSTすると、モデルの子リストが表示されます。

[HttpPost] 
public ActionResult Create(Parent model) 
{ 

    var newChildren = model.Children.Where(s => !s.IsDeleted && s.ChildId == 0); 

    var updated = model.Children.Where(s => !s.IsDeleted && s.ChildId != 0); 

    var deletedChildren = model.Children.Where(s => s.IsDeleted && s.ChildId != 0); 


    return View(model); 
} 

GrandChildrenと同様の操作を行う必要があります。

+1

うわー、実際に働いて、今あなたの例のおかげで、私はHtml.BeginCollectionItemの使い方をよく理解しています。 回答としてマーク: –

関連する問題