簡體   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