Search code examples
htmlangularjsangularjs-ng-repeatangularjs-filterangularjs-ng-model

Get the count of nested ng-repeat in the outermost ng-repeat and update in dynamically according to ng-model value


I have three nested ng-repeat to display the drives their corresponding folders and their corresponding files. A sample data is shown below

Drives=[  
   {  
      name:'C Drive',
      folders:[  
         {  
            name:'personal',
            files:[  
               {  
                  name:'a.txt'
               },
               {  
                  name:'b.txt'
               }
            ]
         }
      ]
   }
]

So I have three nested ng-repeat to display the drive name, its folders and the files in the folders. How to get the total number of files in a drive and display it along the drive name.

Sample code

<div ng-repeat="drive in drives">
{{drive.name}} <I want the total count of files in a drive here>
    <div ng-repeat="folder in drive.folders">
    {{folder.name}} {{filteredfiles.length}}
        <div ng-repeat="file in filteredfiles=(folder.files | filter 
        {name:search})">
        {{file.name}}
        </div>
    </div>
</div>
<input type="text" ng-model="search"/>

Note that I have a search filter so the number of files in a drive should get updated dynamically according to the filter value applied to denote the number of files with the same name as the search value in a particular drive.

How to incrementally count the number of files in a drive and apply two way binding such that the count gets updated according to the search value ?

For Angular version 1.6


Solution

  • Modify filteredfiles so that they are contained in a controller object that you can iterate to get total length of all the arrays. Use index of drive for first level keys and folder index for next level.

    Then use a controller function that uses Array#reduce ( or a for in loop) to iterate all the various object keys to sum all the array lengths

    View:

     <div ng-repeat="drive in drives">
    
        <strong>{{drive.name}}</strong>  -- File count:{{filteredFileCount($index)}}
    
        <div ng-repeat="folder in drive.folders" ng-init="driveIndex = $parent.$index">
         {{folder.name}} has {{filteredfiles[driveIndex][$index].length}} files
         <ul>
            <li ng-repeat="file in filteredfiles[driveIndex][$index]=(folder.files | filter:{name:search} ) ">
            {{file.name}}
          </li>
         </ul>
    
        </div>
      </div>
    

    Controller: (or put business logic in service)

      // object to hold arrays filtered in view
      $scope.filteredfiles = {};
    
      $scope.filteredFileCount = function(driveIndex) {
    
        let driveObj = $scope.filteredfiles[driveIndex] || {};
    
        return  Object.keys(driveObj).reduce((a, c) => {
          return a + (Array.isArray(driveObj[c]) ? driveObj[c].length : 0);
        }, 0);
    
      }
    

    DEMO