2015-04-17 62 views
5

單擊按鈕時添加/刪除行的最佳方式是什麼?我需要從ChildClass屬性創建的行(子類是主類/模型中的列表)。MVC 5動態行與BeginCollectionItem

當前有一個視圖(模型是MyMain),它使用RenderPartial引用部分視圖。

局部視圖顯示模型的屬性,這是一個名爲MyChild的類,它是MyMain中的對象列表。

我想要添加和刪除按鈕來動態添加部分視圖中保存的行。

因此,爲列表上的更多行重複添加MyChild。 這可能嗎?或者我應該不使用部分視圖?

更新的代碼

下面是當前類和意見,我有,我一直在努力實現BeginCollectionItem助手的工作,但我發現在那裏我試圖加載空裁判部分視圖,儘管if語句說創建子類的新實例如果不存在 - 爲什麼這被忽略?

主視圖

@using (Html.BeginForm()) 
{ 
    <table> 
     <tr> 
      <th>MyMain First</th> 
      <th>MyChild First</th> 
     </tr> 
     <tr> 
      <td> 
       @Html.EditorFor(m => m.First) 
      </td> 
      <td> 
       @if (Model.child != null) 
       { 
        for (int i = 0; i < Model.child.Count; i++) 
        { 
         Html.RenderPartial("MyChildView"); 
        } 
       }   
       else 
       { 
        Html.RenderPartial("MyChildView", new MvcTest.Models.MyChild()); 
       }  
      </td> 
     </tr> 
     @Html.ActionLink("Add another", "Add", null, new { id = "addItem" }) 
    </table> 
} 

管窺

@model MvcTest.Models.MyChild 

@using (Html.BeginCollectionItem("myChildren")) 
{ 
    Html.EditorFor(m => m.Second); 
} 

模式

public class MyMain 
{ 
    [Key] 
    public int Id { get; set; } 
    public string First { get; set; } 
    public List<MyChild> child { get; set; } 
} 

public class MyChild 
{ 
    [Key] 
    public int Id { get; set; } 
    public string Second { get; set; } 
} 

控制器

public class MyMainsController : Controller 
{ 
    // GET: MyMains 
    public ActionResult MyMainView() 
    { 
     return View(); 
    } 

    [HttpPost] 
    public ActionResult MyMainView(IEnumerable<MyChild> myChildren) 
    { 
     return View("MyMainView", myChildren); 
    } 

    public ViewResult Add() 
    { 
     return View("MyChildView", new MyChild()); 
    } 
} 
+3

動態地添加和刪除對象[這裏]一些選項(http://stackoverflow.com/questions/29161481/post-a-form-array-without-successful/29161796# 29161796)和[這裏](http://stackoverflow.com/questions/28019793/submit-same-partial-view-called-multiple-times-data-to-controller/28081308#28081308) –

+0

就像這樣:https: //github.com/danludwig/BeginCollectionItem –

+0

謝謝@StephenMuecke我剛剛回顧了你的建議 - BeginCollectionItem在其中一個答案中提到了最佳方式嗎?看起來非常混亂。基本上我希望能夠按照客戶想要的方式添加子模型屬性(將有進一步的驗證,但在以後的日期)。是否使用局部視圖來達到這個目的?歡呼你的幫助。 – PurpleSmurph

回答

8

更新回答 - 原代碼是真實的「動態」,但是它允許我需要這個問題的參數範圍內所做的一切。

最初,我無法在問題評論工作中得到斯蒂芬BCI的建議,因爲那時我已經很出色了。如果您複製+粘貼,更新部分中的以下代碼將起作用,但您需要從GIT手動下載BCI,或者在Visual Studio中將包裝管理器控制檯與PM> Install-Package BeginCollectionItem配合使用。

由於複雜性以及之前未完成MVC,我在使用BCI的各個點上遇到了一些問題 - 有關處理訪問class.property(type class).property(type class).property的更多信息,請參閱here

原始回答 - 我已經拿到了一個比我的問題更加清晰的例子,這個問題很快就讓人感到困惑。

使用兩個部分景色,一個員工的名單,另一個是包含companyemployee的其中包含公司的目標和員工的對象列表視圖模型中創建一個新員工的全部。通過這種方式,可以從列表中添加,編輯或刪除多個員工。

希望這個答案將幫助任何人在尋找類似的東西,這應該提供足夠的代碼,得到它的工作,並至少是推你在正確的方向。

我已經離開了我的背景和初始化器類,因爲他們是唯一真正的代碼首先,如果需要,我可以將它們添加。

感謝所有幫助。

模式 - CompanyEmployee是視圖模型

public class Company 
{ 
    [Key] 
    public int id { get; set; } 
    [Required] 
    public string name { get; set; } 
} 

public class Employee 
{ 
    [Key] 
    public int id { get; set; } 
    [Required] 
    public string name { get; set; } 
    [Required] 
    public string jobtitle { get; set; } 
    [Required] 
    public string number { get; set; } 
    [Required] 
    public string address { get; set; } 
} 

public class CompanyEmployee 
{ 
    public Company company { get; set; } 
    public List<Employee> employees { get; set; } 
} 

指數

@model MMV.Models.CompanyEmployee 
@{ 
    ViewBag.Title = "Index"; 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 

<h2>Index</h2> 
<fieldset> 
    <legend>Company</legend> 
    <table class="table"> 
     <tr> 
      <th>@Html.LabelFor(m => m.company.name)</th> 
     </tr> 
     <tr> 
      <td>@Html.EditorFor(m => m.company.name)</td> 
     </tr> 
    </table> 
</fieldset> 
<fieldset> 
    <legend>Employees</legend> 

     @{Html.RenderPartial("_employeeList", Model.employees);} 

</fieldset> 
<fieldset> 
    @{Html.RenderPartial("_employee", new MMV.Models.Employee());} 
</fieldset> 
<div class="form-group"> 
    <div class="col-md-offset-2 col-md-10"> 
     <input type="submit" value="Submit" class="btn btn-default" /> 
    </div> 
</div> 

員工名單的PartialView

@model IEnumerable<MMV.Models.Employee> 
@using (Html.BeginForm("Employees")) 
{ 
    <table class="table"> 
     <tr> 
      <th> 
       Name 
      </th> 
      <th> 
       Job Title 
      </th> 
      <th> 
       Number 
      </th> 
      <th> 
       Address 
      </th> 
      <th></th> 
     </tr> 
     @foreach (var emp in Model) 
     { 
      <tr> 
       <td> 
        @Html.DisplayFor(modelItem => emp.name) 
       </td> 
       <td> 
        @Html.DisplayFor(modelItem => emp.jobtitle) 
       </td> 
       <td> 
        @Html.DisplayFor(modelItem => emp.number) 
       </td> 
       <td> 
        @Html.DisplayFor(modelItem => emp.address) 
       </td> 
       <td> 
        <input type="submit" formaction="/Employees/Edit/@emp.id" value="Edit"/> 
        <input type="submit"formaction="/Employees/Delete/@emp.id" value="Remove"/> 
       </td> 
      </tr> 
     } 
    </table> 
} 

局部視圖中創建員工

@model MMV.Models.Employee 

@using (Html.BeginForm("Create","Employees")) 
{ 
    <table class="table"> 

     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 

     <tr> 
      <td> 
       @Html.EditorFor(model => model.name) 
       @Html.ValidationMessageFor(model => model.name, "", new { @class = "text-danger" }) 
      </td> 
      <td> 
       @Html.EditorFor(model => model.jobtitle) 
       @Html.ValidationMessageFor(model => model.jobtitle) 
      </td> 
      <td> 
       @Html.EditorFor(model => model.number) 
       @Html.ValidationMessageFor(model => model.number, "", new { @class = "text-danger" }) 
      </td> 
      <td> 
       @Html.EditorFor(model => model.address) 
       @Html.ValidationMessageFor(model => model.address, "", new { @class = "text-danger" }) 
      </td> 
     </tr> 
    </table> 
    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Create" class="btn btn-default" /> 
     </div> 
    </div> 
} 

控制器 - 我用了數倍,但你可以把他們都在一個

public class CompanyEmployeeController : Controller 
{ 
    private MyContext db = new MyContext(); 

    // GET: CompanyEmployee 
    public ActionResult Index() 
    { 
     var newCompanyEmployee = new CompanyEmployee(); 
     newCompanyEmployee.employees = db.EmployeeContext.ToList(); 
     return View(newCompanyEmployee); 
    } 

    [HttpPost, ActionName("Delete")] 
    public ActionResult DeleteConfirmed(int id) 
    { 
     Employee employee = db.EmployeeContext.Find(id); 
     db.EmployeeContext.Remove(employee); 
     db.SaveChanges(); 
     return RedirectToAction("Index", "CompanyEmployee"); 
    } 

    [HttpPost] 
    public ActionResult Create([Bind(Include = "id,name,jobtitle,number,address")] Employee employee) 
    { 
     if (ModelState.IsValid) 
     { 
      db.EmployeeContext.Add(employee); 
      db.SaveChanges(); 
      return RedirectToAction("Index", "CompanyEmployee"); 
     } 

     return View(employee); 
    } 
} 

更新的代碼 - 使用BeginCollectionItem - 動態添加/刪除

學生部分

@model UsefulCode.Models.Person 
<div class="editorRow"> 
    @using (Html.BeginCollectionItem("students")) 
    { 
     <div class="ui-grid-c ui-responsive"> 
      <div class="ui-block-a"> 
       <span> 
        @Html.TextBoxFor(m => m.firstName) 
       </span> 
      </div> 
      <div class="ui-block-b"> 
       <span> 
        @Html.TextBoxFor(m => m.lastName) 
       </span> 
      </div> 
      <div class="ui-block-c"> 
       <span> 
        <span class="dltBtn"> 
         <a href="#" class="deleteRow">X</a> 
        </span> 
       </span> 
      </div> 
     </div> 
    } 
</div> 

教師部分

@model UsefulCode.Models.Person 
<div class="editorRow"> 
    @using (Html.BeginCollectionItem("teachers")) 
    { 
     <div class="ui-grid-c ui-responsive"> 
      <div class="ui-block-a"> 
       <span> 
        @Html.TextBoxFor(m => m.firstName) 
       </span> 
      </div> 
      <div class="ui-block-b"> 
       <span> 
        @Html.TextBoxFor(m => m.lastName) 
       </span> 
      </div> 
      <div class="ui-block-c"> 
       <span> 
        <span class="dltBtn"> 
         <a href="#" class="deleteRow">X</a> 
        </span> 
       </span> 
      </div> 
     </div> 
    } 
</div> 

註冊控制器

public ActionResult Index() 
{ 
    var register = new Register 
    { 
     students = new List<Person> 
     { 
      new Person { firstName = "", lastName = "" } 
     }, 
     teachers = new List<Person> 
     { 
      new Person { lastName = "", firstName = "" } 
     } 
    }; 

    return View(register); 
} 

註冊和角色模型

public class Register 
{ 
    public int id { get; set; } 
    public List<Person> teachers { get; set; } 
    public List<Person> students { get; set; } 
} 

public class Person 
{ 
    public int id { get; set; } 
    public string firstName { get; set; } 
    public string lastName { get; set; } 
} 

指數

@{ 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
} 
@model UsefulCode.Models.Register 
<div id="studentList"> 
@using (Html.BeginForm()) 
{ 
    <div id="editorRowsStudents"> 
     @foreach (var item in Model.students) 
     { 
      @Html.Partial("StudentView", item) 
     } 
    </div> 
    @Html.ActionLink("Add", "StudentManager", null, new { id = "addItemStudents", @class = "button" }); 
} 
</div> 

<div id="teacherList"> 
@using (Html.BeginForm()) 
{ 
    <div id="editorRowsTeachers"> 
     @foreach (var item in Model.teachers) 
     { 
      @Html.Partial("TeacherView", item) 
     } 
    </div> 
    @Html.ActionLink("Add", "TeacherManager", null, new { id = "addItemTeachers", @class = "button" }); 
} 
</div> 


@section scripts { 
    <script type="text/javascript"> 
    $(function() { 
     $('#addItemStudents').on('click', function() { 
      $.ajax({ 
       url: '@Url.Action("StudentManager")', 
        cache: false, 
        success: function (html) { $("#editorRowsStudents").append(html); } 
       }); 
       return false; 
      }); 
      $('#editorRowsStudents').on('click', '.deleteRow', function() { 
       $(this).closest('.editorRow').remove(); 
      }); 
      $('#addItemTeachers').on('click', function() { 
       $.ajax({ 
        url: '@Url.Action("TeacherManager")', 
        cache: false, 
        success: function (html) { $("#editorRowsTeachers").append(html); } 
       }); 
       return false; 
      }); 
      $('#editorRowsTeachers').on('click', '.deleteRow', function() { 
       $(this).closest('.editorRow').remove(); 
      }); 
     }); 
    </script> 
} 

StudentManager操作:

public PartialViewResult StudentManager() 
{ 
    return PartialView(new Person()); 
} 
+0

post方法應該如何? –

+0

對不起,我不明白你的意思? – PurpleSmurph

+0

當我使用註冊模型發佈主視圖索引時,在發佈後,它返回教師和學生屬性中的0項。 –

1

可以使用局部視圖它,但問題是,與EditorFor產生的Id特性導致生成重複。

我的工作是在我的主視圖中使用var view = @Html.Raw(@Html.Partial('Your partial')) JavaScript內部。

這個變量,然後將與默認IDS的觀點,然後我和id=YourMainListName_{ItemNumber}__Propertyname=YourMainListName_{ItemNumber}__Property

更換ID屬性和名稱屬性在哪裏{ItemNumber}將在列表中選擇新項目的索引。

它需要大量的JavaScript才能正常工作,但只要您具有正確設置的Id和Name屬性,一切都應該正常工作,包括回發頁面時的模型綁定。