3

我一直在這個問題上撞了我的頭幾天,現在無法弄清楚。我需要創建一個允許用戶添加和刪除複雜分層對象的視圖。假例如:我可以使用添加/刪除功能顯示MVC 4視圖中的複雜對象列表嗎?

模式

public class ParentModel 
{ 
    public int ParentId { get; set; } 
    public string ParentText { get; set; } 
    public IList<ChildModel> Children { get; set; } 
} 
public class ChildModel 
{ 
    public int ChildId { get; set; } 
    public string ChildText { get; set; } 
    public IList<GrandChildModel> GrandChildren { get; set; } 
} 
public class GrandChildModel 
{ 
    public int GrandChildId { get; set; } 
    public string GrandChildText { get; set; } 
} 

現在,假設我有填充一個ParentModel的動作和它的子屬性,一個簡單的觀點看起來是這樣的:

@model EditorTemplateCollectiosns.Models.ParentModel 
@using (@Html.BeginForm()) 
{ 
    <div> 
     @Html.TextBoxFor(m => m.ParentId) 
     @Html.TextBoxFor(m => m.ParentText)<br/> 
     Children:<br/> 
     @for (var i = 0; i < Model.Children.Count; i++) 
     { 
      @Html.TextBoxFor(m => Model.Children[i].ChildId) 
      @Html.TextBoxFor(m => Model.Children[i].ChildText) 
      <div> 
       Grandchildren:<br/> 
       <table id="grandChildren"> 
        <tbody> 
         @for (var j = 0; j < Model.Children[i].GrandChildren.Count; j++) 
         { 
          <tr> 
           <td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildId)</td> 
           <td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildText)</td> 
          </tr> 
         } 
        </tbody> 
       </table> 
      </div> 
     } 
    </div> 
    <button type="button" id="addGrandchild">Add Grandchild</button> 
    <input type="submit" value="submit"/> 
} 
<script type="text/javascript"> 
    $(document).ready(function() { 
     $("#addGrandchild").click(function() { 
      $("#grandChildren tbody:last").append('<tr><td><input type="text" name="grandChildId" /></td><td><input type="text" name="grandChildText" /></td></tr>'); 
     }); 
    }); 
</script> 

這種觀點除非我添加孫子並提交表單,否則它不會與GrandChildModel列表綁定。在POST的小提琴:

Post after adding grandchild

所以我試圖用一個編輯模板GrandChildModel,只是爲了看看它是否會工作。這個功能很好地簡單地顯示對象,但我不知道如何將一個孫子添加到列表中並讓它顯示在編輯器模板中。我也嘗試嵌入部分視圖加載$.ajax調用,但這變成了一個後勤噩夢。

在實際的應用程序中,層次結構比這個例子更深,並且每個連續的子對象都需要具有這種添加/刪除功能。每次用戶想要添加或刪除一個對象時,甚至可能沒有表單的完整文章?通過上面示例中的方法,是否可以在POST上將新添加的孫子女綁定到IList?或者,有沒有辦法在客戶端添加對象,並在編輯器模板上綁定到POST上的IList?如果兩種選擇都不是正確的方法,那是什麼?

UPDATE
我已經想通了的東西哈克可能的工作,但我還是很想知道,如果有這樣做的更簡單的方法。我將上面的視圖代碼更改爲:

@model EditorTemplateCollectiosns.Models.ParentModel 
@using (@Html.BeginForm()) 
{ 
    <div> 
     @Html.TextBoxFor(m => m.ParentId) 
     @Html.TextBoxFor(m => m.ParentText)<br/> 
     Children:<br/> 
     <button type="button" id="addChild" onclick="addChildRow()">Add Child</button> 
     <table id="children"> 
      <tbody class="childTableBody"> 
       @for (var i = 0; i < Model.Children.Count; i++) 
       { 
        <tr> 
         <td colspan="3">Child @i</td> 
        </tr> 
        <tr class="childInfoRow"> 
         <td> 
          @Html.TextBoxFor(m => Model.Children[i].ChildId) 
         </td> 
         <td> 
          @Html.TextBoxFor(m => Model.Children[i].ChildText)        
         </td> 
         <td> 
          <button type="button" id="[email protected](i)" onclick="removeChildRow(this)">Delete</button> 
         </td> 
        </tr> 
        <tr> 
         <td colspan="3"> 
          Grandchildren:<br/> 
          <button type="button" id="[email protected](i)" onclick="addGrandchildRow(this)">Add Grandchild</button> 
          <table id="[email protected](i)"> 
           <tbody> 
            @for (var j = 0; j < Model.Children[i].GrandChildren.Count; j++) 
            { 
             <tr> 
              <td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildId)</td> 
              <td>@Html.TextBoxFor(m => @Model.Children[i].GrandChildren[j].GrandChildText)</td> 
              <td><button type="button" id="[email protected](i)[email protected](j)" onclick="removeGrandchildRow(this)">Delete</button></td> 
             </tr> 
            } 
           </tbody> 
          </table> 
         </td> 
        </tr> 
       } 
      </tbody> 
     </table> 
    </div> 
    <input type="submit" value="submit"/> 
} 

然後,我添加了以下javascript。我不能使用類和jQuery click事件處理程序重新綁定的處理程序後,各添加/刪除似乎不工作的權利:

<script type="text/javascript"> 
    function addChildRow() { 
     var newRowIndex = $("#children tr.childInfoRow").length; 
     var newRow = '<tr><td colspan="3">Child ' + newRowIndex + '</td></tr><tr class="childInfoRow"><td><input type="text" name="Children[' + newRowIndex + '].ChildId" /></td>' + 
      '<td><input type="text" name="Children[' + newRowIndex + '].ChildText" /></td>' + 
      '<td><button type="button" id="removeChild' + newRowIndex + '" onclick="removeChildRow(this)">Delete</button></td></tr>' + 
      '<td colspan="3">Grandchildren: <br/><button type="button" id="addGrandchild' + newRowIndex + '" onclick="addGrandchildRow(this)">Add Grandchild</button>' + 
      '<table id="grandChildren' + newRowIndex + '"><tbody></tbody></table></td></tr>'; 
     $("#children tbody.childTableBody:last").append(newRow); 
    } 
    function addGrandchildRow(elem) { 
     var childIndex = $(elem).attr('id').replace('addGrandchild', ''); 
     var newRowIndex = $("#grandChildren" + childIndex + " tr").length; 
     var newRow = '<tr><td><input type="text" name="Children[' + childIndex + '].GrandChildren[' + newRowIndex + '].GrandChildId" /></td>' + 
      '<td><input type="text" name="Children[' + childIndex + '].GrandChildren[' + newRowIndex + '].GrandChildText" /></td>' + 
      '<td><button type="button" id="removeGrandchild' + childIndex + '_' + newRowIndex + '" onclick="removeGrandchildRow(this)">Delete</button></td></tr>'; 
     $("#grandChildren" + childIndex + " tbody:last").append(newRow); 
    } 
    function removeChildRow(elem) { 
     $(elem).closest('tr').prev().remove(); 
     $(elem).closest('tr').next().remove(); 
     $(elem).closest('tr').remove(); 
    } 
    function removeGrandchildRow(elem) { 
     $(elem).closest('tr').remove(); 
    } 
</script> 

到目前爲止,這是工作,並且陣列價值觀似乎正確地綁定。然而,我並不是要將大量行添加到任何表中的大量東西的巨大粉絲。有沒有人有更好的主意?

回答

0

我最終使用在編輯我原來的職位的解決方案。這是一個JavaScript的,花了很長時間來測試,但它的工作原理,是我能找到的唯一途徑。如果有人對完整的解決方案感興趣,請在這裏留言,我會發布。

0

如果您僅使用一個模型,則更容易實現。 ChildModel和GrandChildModel只有HierarchichalPersonModel,而不是ParentModel。

這樣你只需要一個視圖和一個自定義編輯器模板。阿賈克斯會更難一點,但不是你描述的邏輯噩夢。

更新:新增例子

角色模型:

public class Person 
{ 
    public int Id { get; set; } 
    public string Text { get; set; } 
    public List<Person> Children { get; set; } 
} 

假庫:

public static List<Person> PersonCollection { get; set; } 

public static Person FindById(int id, List<Person> list = null) 
{ 
    if (list == null) 
     list = PersonCollection; 

    foreach (var person in list) 
    { 
     if (person.Id == id) 
      return person; 

     if (person.Children != null) 
      return FindById(id, person.Children); 
    } 

    return null; 
} 
+0

我會在一兩分鐘 – amhed 2013-04-07 14:23:15

+0

我不關心庫代碼的更新一個例子,但是我專注如何以允許添加和刪除從層次結構的項目顯示它。更多的視圖/控制器的東西比數據訪問/存儲庫。 – 2013-04-08 14:19:32

+0

是否需要同時向控制器發送多個項目?因爲我認爲使用AJAX一對一添加新項目會更容易。我可以發佈一個例子,如果你想:) – amhed 2013-04-08 19:05:44

相關問題