AngularJS ng-repeat-start/end遍历同实体嵌套结构异常问题
我之前也碰到过这种嵌套ng-repeat-start/end的坑,尤其是处理递归结构的时候,很容易因为指令配对错误导致深层级数据不渲染。既然Batarang已经确认grandSon.Name有数据,那问题肯定出在ng-repeat的嵌套结构或者作用域传递上,给你两个可行的解决方案:
方案1:使用递归模板(推荐,支持任意层级)
你的ParentChiled是自嵌套的递归结构,用递归模板处理是最优雅的方式,不管多少层嵌套都能自动适配,完全不会出现深层级不渲染的问题。
首先在Razor视图里定义一个递归模板:
<script type="text/ng-template" id="familyMemberTemplate.html"> <!-- 渲染当前节点的名称 --> <div>{{ member.Name }}</div> <!-- 如果当前节点有子节点,递归渲染每个子节点 --> <div ng-repeat="child in member.Child"> <ng-include src="'familyMemberTemplate.html'" ng-init="member = child"></ng-include> </div> </script>
然后在主视图里调用这个模板,传入根节点GrandPa:
<!-- 先渲染根节点GrandPa的名称 --> <div>{{ GrandPa.Name }}</div> <!-- 递归渲染GrandPa的所有子节点及后代 --> <div ng-repeat="child in GrandPa.Child"> <ng-include src="'familyMemberTemplate.html'" ng-init="member = child"></ng-include> </div>
这种写法逻辑清晰,不需要纠结ng-repeat-start/end的配对问题,后续如果层级增加也不需要修改代码。
方案2:修正ng-repeat-start/end的嵌套结构(适合固定层级)
如果你一定要用ng-repeat-start/end,必须保证每一个ng-repeat-start都有对应的ng-repeat-end,且嵌套层级完全匹配。之前的问题大概率是你少写了某个ng-repeat-end,或者end的位置错位,导致第三层循环没有被正确包裹在父层级作用域里。
正确的三层嵌套写法应该是这样的:
<!-- 第一层:GrandPa的子节点(Dad) --> <div ng-repeat-start="dad in GrandPa.Child"> {{ dad.Name }} <!-- 第二层:Dad的子节点(Son) --> <div ng-repeat-start="son in dad.Child"> {{ son.Name }} <!-- 第三层:Son的子节点(GrandSon) --> <div ng-repeat-start="grandSon in son.Child"> {{ grandSon.Name }} </div> <!-- 对应GrandSon的ng-repeat-start --> <div ng-repeat-end></div> </div> <!-- 对应Son的ng-repeat-start --> <div ng-repeat-end></div> </div> <!-- 对应Dad的ng-repeat-start --> <div ng-repeat-end></div>
每个ng-repeat-start必须和ng-repeat-end一一对应,位置不能错位。不过这种写法只适合你确定层级固定的情况,后续如果层级扩展,代码维护成本会很高。
额外提醒
可以在ParentChiled类的构造函数里初始化Child = new List<ParentChiled>(),避免因为Child为null导致ng-repeat不执行;另外用Batarang检查每个ng-repeat创建的子作用域,确认grandSon确实在对应作用域中,排除作用域继承的问题。
内容的提问来源于stack exchange,提问作者user9795291

