繁体   English   中英

当递归地重复ng-repeat时,如何在ng-include中获取父元素

[英]How to get parent element inside ng-include when iterating in ng-repeat recursively

我做了一个递归的ng-repeat元素,并试图操纵事物变成了一场噩梦,因为我没有引用我正在迭代的父。

ng-repeat看起来像这样:

ng-repeat="(key, value) in value"

记住它是递归的,因此值中的每个值都成为新值,因此我不能只使用ng-repeat中的“in”值。 我想做的事情是检查父是否是一个数组,但是$ parent是一些奇怪的东西,而不是当前迭代值的父元素。

我想要做的一些事情的例子是:

ng-show="isArray(parent)"
ng-click="delete(parent, $index)"

(作为我正在做的工作的一个例子,我必须为每个数组元素添加一个___ISARRAYELEMENT___属性,只是为了知道它在一个数组中>。> ;;)

编辑:基本上我想知道在我重复的ng-repeat上下文中是否有任何方便的元数据。

编辑:好的,这里的html是完整的:

<html ng-app>
<head>
    <title>JSON CRUD</title>
    <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.6/angular.min.js"></script>
    <script src="angularjsoncrud.js"></script>
    <script type="text/ng-template" id="node.html">
        <button ng-click="minimized = !minimized" ng-show="!isLeaf(value)" ng-init="minimized=false" ng-class="{'glyphicon glyphicon-plus': minimized, 'glyphicon glyphicon-minus': !minimized}">-</button>
        <input ng-model="value.___KEY___" ng-if="!isArrayElement(value)" />
        <input ng-if="isLeaf(value)" ng-model="value.___VALUE___" />
        <ul ng-if="!isLeaf(value)" ng-show="!minimized">
            <li ng-repeat="(key,value) in value" ng-if="key != '___KEY___' && key != '___ISARRAY___'" ng-include="'node.html'"></li>
            <button type="button" ng-if="isArray(value)" ng-click="addToArray(value)">Add Element</button>
        </ul>
    </script>
</head>
<body ng-app="Application" ng-controller="jsoncrudctrl">
    <ul>
        <li ng-repeat="(key,value) in json" ng-include="'node.html'"></li>
    </ul>
    <pre>{{stringify(json)}}</pre>
</body>
</html>

我想做的一件事是用isArray(parent)替换isArrayElement(value),因为isArrayElement依赖于我添加到数组的元数据,我宁愿不必添加。

ng-repeat为每个元素创建一个新范围。
ng-include还会创建一个新范围。

ng-includeng-repeat一起使用时,为每个元素创建了两个范围:

  • ng-repeat为当前元素创建的范围。 此范围保存迭代中的当前元素。
  • ng-include创建的子范围 ,它继承ng-repeat的创建范围。

当前作用域的$parent属性允许您访问其父作用域。

从本质上讲, ng-include创建的范围是空的,当您在node.html访问valuekey时,它实际上访问了ng-repeat创建的父范围中的继承值

在您的node.html中,访问{{value}}实际上与{{$parent.value}} 因此,如果您需要访问当前元素的父元素,则必须通过访问{{$parent.$parent.value}}

这个DEMO将清理:

    <script type="text/ng-template" id="node.html">
        <div>
            Current: key = {{key}}, value = {{value}}
        </div>
        <div>
            Current (using $parent): key = {{$parent.key}}, value = {{$parent.value}}
        </div>
         <div>
             Parent: key = {{$parent.$parent.key}}, value = {{$parent.$parent.value}}, isArray: {{isArray($parent.$parent.value)}}
        </div>
        <ul ng-if="isObject(value)"> //only iterate over object to avoid problems when iterating a string
<li ng-repeat="(key,value) in value" ng-include="'node.html'"></li>            
        </ul>
    </script>

如果您需要简化访问父级的方式,可以尝试使用ng-include onload初始化父ng-include 像这样:

在您的顶级,没有ng-if =>只有2级深度

<ul>
    <li ng-repeat="(key,value) in json" 
     ng-include="'node.html'" onload="parent=$parent.$parent"></li>
</ul>

在您的子级别中,有ng-if => 3级别:

    <ul ng-if="isObject(value)">
        <li ng-repeat="(key,value) in value" 
ng-include="'node.html'" onload="parent=$parent.$parent.$parent"></li>            
    </ul>

在模板内部,您可以使用parent ,祖父母使用parent.parent访问parent ,依此类推。

DEMO

我会远离Angular的$parent和所有$scope创建和继承疯狂。 你需要的是保持对父对象的引用,而不是在ng-includeng-repeat之间找到多少范围,并且用$parent.$parent 我的建议是明确保存对您感兴趣的值的引用 ,只需使用自定义逻辑自行实现。 例如,如果要将父ng-repeat中的值公开给子ng-repeat

<!-- Explictly save the value into the parent var -->
<div ng-init="parent = value">
  <!-- Save parent reference and
       update the parent var to point to the new value -->
  <div ng-repeat="(k,value) in value"
       ng-init="value._parent = parent; parent = value;"> 
    <div ng-repeat="(k,value) in value"
         ng-init="value._parent = parent">
      <button ng-click="doSomething(value)"></button>
    </div>
  </div>
</div>

然后在您的JavaScript代码中,您可以递归访问所有父项

function doSomething(value){
  parent1 = value._parent;
  parent2 = parent1._parent;
}

ng-include相同的代码

<div ng-init="parent = value">
  <div ng-repeat="(key,value) in value"
       ng-init="value._parent = parent; parent = value;"
       ng-include="'node.html'">
  </div>
</div>

<script type="text/ng-template" id="node.html">
  <div ng-if="!isLeaf(value)"
       ng-repeat="(key,value) in value"
       ng-init="value._parent = parent; parent = value;"
       ng-include="'node.html'"> 

  <button ng-if="isLeaf(value)" ng-click="doSomething(value)"></button>
</script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM