简体   繁体   中英

Extending the scope of $index when using ng-repeat in angularjs

I need to use the value of the $index inside a ng-repeat directive out of its scope. I have tried a couple of workarounds but haven't been successful.

Here is my code:

<tbody ng-init="countObj={"count":0}" >
            <tr ng-repeat="data in result.data1" ng-init="index1 = $index" ng-if='result.data1'>
                <td>{{countObj.count = index1+1}}</td> // here I assing index1 to parent scope count
                <td>{{data}}{{countObj.count}}</td> // here count has the correct value
                <td>{{result.data2[$index]}}</td>                   
            </tr>
            <tr ng-repeat="data in result.data3" ng-init="index2 = $index" ng-if='result.data3'>
                <td>{{index2+countObj.count}}</td> // here I add count to index2
                <td>{{result.data3[$index]}}{{countObj.count}}</td> // here count has no value
                <td>{{result.data4[$index]}}</td>
            </tr>
            <tr ng-if='result.data1 == undefined && result.data3 == undefined'>
                <td><strong>No data to display.</strong></td>
            </tr>
</tbody>

This complete table is inside a custom directive I have just posted the tbody tag.

Directive is as follows:

<concept-details ng-repeat = "result in searchRes.list"></concept-details>

The data is rendering absolutely fine it is just the count which I am unable to get in the second tr tag.

I tested the above workaround on w3school and it works just fine. Here is the code i tested:

<table>
<thead>
<tr>
    <th>S No.</th>
    <th>Header 1</th>
    <th>Header 2</th>

</tr>
</thead>
<tbody ng-init="count" >
    <tr ng-init="test = 5">
        <td>test is</td>
        <td>{{count = test}}</td>
        <td>end</td>
    </tr>
    <tr ng-init="test2 = 10">
        <td>test 2 is</td>
        <td>{{count + test2}}</td>
        <td>end</td>
    </tr>
</tbody>
</table>

I'm fairly new to angularjs so kindly excuse any mistake I might have made.

Any suggestions are highly appreciated.

Thanks in advance.

Edit: Code changed to Naveen Kumar's suggestion but still same output

For ng-repeat scope creation works differently. For each loop, ng-repeat creates a new scope, which inherits from parent but there's a catch here If the property is primitive as count in your case it justs create a copy in the child scope. The code of ng-repeat is as follows

      childScope = scope.$new(); 
      childScope[valueIdent] = value;

count ($scope) copied to countCopy($childScope)

So the increment on your count property is done on a local copy of count inside your first loop.

So all your increments are not reflected in the main count in your scope. Workaround would be to make count as property inside an object. If you change it to an object property then a copy of object would be made which would still have reference to the same main count property.

countObj ($scope) copied to countObjCopy($childScope)

both countObj and countObjCopy refer to same property count

   //while initializing
   <tbody ng-init="countObj={"count":0}" >

   //while incrementing 
   <td>{{countObj.count= index1+1}}

On further drilling down it seems there's more problem than caused due to child scope creation. I have commented on issue and its more related to angular infinite digest error caused by updated scope variables inside view rendering. Refer here for more https://docs.angularjs.org/error/ $rootScope/infdig

So the best approach would be to update count obj outside view content

One of the workaround is to use as follows is to update countobj's count in init of the first loop itself and use index to display

<tbody ng-init="countObj={'count':result.data1.length}" >
         <tr ng-repeat="data in result.data1" ng-init="index1 = $index"  ng-if='result.data1'>
            <td>{{index1+1}}</td> // here I assing index1 to parent scope count
            <td>{{data}}{{index1+1}}</td> // here count has the correct value
            <td>{{result.data2[$index]}}</td>                     
        </tr>
          <tr ng-repeat="data in result.data3" ng-init="index2 = $index" ng-if='result.data3'>
            <td>{{index2+countObj.count+1}}</td> // here I add count to index2
            <td>{{result.data3[$index]}}{{countObj.count}}</td> // here count has no value
            <td>{{result.data4[$index]}}</td>
        </tr>
</tbody>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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