目标:
具有无限深度的嵌套元素层次结构。
问题:
我有一个A类,其中包含一个B类实例。
B类有一个Comment对象列表。每个评论可能都有一个“孩子”评论列表。
因此,我们有一个树状结构,无限深度嵌套(例如A.B.Comments [1]。评论[0]。评论[5] ....)。
A类编辑查看电话:
@Html.EditorFor(m=>m.B)
B组的编辑模板有(简化):
<table id="B-comments">
@for (int i = 0; i < Model.Comment.ToList().Count(); i++)
{
@Html.EditorFor(m => m.Comment.ToList()[i])
}
</table>
<a id="addCommentToB" href="#">Add Comment</a>
Comment类的每个Editor Template都包含(简化):
<tr>
@using (Html.BeginCollectionItem("B.Comment"))
{
<td>
(... STUF ...)
</td>
(...STUF...)
<td>
<table class ="commentReplies">
@for (int i = 0; i < Model.Comment1.ToList().Count(); i++)
{
@Html.EditorFor(m => m.Comment1.ToList()[i])
}
</table>
<a id="addReply" href="#">Add Reply</a>
</td>
}
<a ...>
链接用于通过Ajax获取条目行,并将它们附加到相应的表中。
提交时,绑定仅适用于第一个嵌套级别(A.B.Comments,但不适用于A.B.Comments中对象的注释)。原因可能是由@using (Html.BeginCollectionItem("B.Comment"))
行引起的,该行仅为1级深度生成索引。
如果有人能给我一个关于如何在这些情况下允许无限制嵌套的建议,我将非常感激。有没有办法动态修改Html.BeginCollectionItem(ARG)?
干杯
编辑:简化的ViewModel,根据要求
public partial class A
{
(...)
public int BID{ get; set; }
public virtual B B{ get; set; }
(...)
}
public partial class B
{
(...)
public virtual ICollection<Comment> Comment { get; set; }
}
public partial class Comment
{
(...)
public Nullable<int> ParentID { get; set; }
public virtual ICollection<Comment> Comment1 { get; set; }
public virtual Comment Comment2 { get; set; }
public virtual B B { get; set; }
public Nullable<int> BID { get; set; }
}
附录:
我最终创建了一个不同的BeginCollectionItem()Html助手,它不会为生成的html的名称和id添加前缀。
E.g:
我的方式,如果我在评论中有评论,Html助手会生成这样的标签:name="*B.Comment[521cfe57-23aa-42d4-9b63-b7fcdd8799c3].*B.Comment.index"
我的新方法只生成name="Entity.Comment.index"
,它允许绑定正常工作。
AlbertoLeón通过提醒我,我不必实际进行深入绑定(例如,将评论的评论绑定到其父级等等)作为捕获评论与评论之间的关系,从而给了我正确的提示。 B对象足以让绑定按我的意愿工作。
答案 0 :(得分:1)
你是以复杂的方式做到这一点。 几年前,我设计了Bside社交引擎,因为没有创建而遗憾地死了。
我发现了同样的问题,它有一个非常简单的解决方案。
您需要为每个内容分配一个guid,并将每个评论视为新内容,这样您就可以随时搜索guid内容。 然后,您只需要使用属性Comments和方法Add,Delete,Edit
创建ICommentable接口然后你需要继承ICommentable的A类,你需要编写实现。对于B来说也一样。
然后在业务层中,您可以从数据库或存储方式获得A和B.并在数据库中搜索A和B注释。当你得到它时,你需要搜索评论的评论。
因此,在存储方式中,评论始终是评论。关于与评论相关的内容项目没有意义。
关于使用ajax的用户界面,我使用了jQuery。 所以不要试图绑定。 将每个评论视为独立对象。 添加注释和保存的每个添加按钮只能引用注释。您只需要使用新注释向MVC方法发送表单。不要忘记父内容项(类A,或B或任何Comment对象)的guid
答案 1 :(得分:0)
您可以使用ViewData.TemplateInfo.GetFullHtmlFieldName()或ViewData.TemplateInfo.HtmlFieldPrefix来检索当前模型的完整路径