Douglas Gaskell Douglas Gaskell - 4 months ago 25
HTML Question

AngularJs - Reference the same scope property from multiple ngRepeat's

I have multiple

ngRepeats
generate table contents, depending on the view the user wants to see, a different
ngRepeat
is used to generate the table. When the user switches their view, and one of the following is removed from the DOM and another added, the new
ngRepeat
does not reference to the same
pagination.filteredData
array.

Example:
Main
is my controller, using
controller as
syntax.

<tr ng-if="Main.tableConfig.programGranularity == 'overall'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.overallData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>

<tr ng-if="Main.tableConfig.programGranularity == 'team'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.teamData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>

<tr ng-if="Main.tableConfig.programGranularity == 'colleague'" ng-repeat="item in Main.pagination.filteredData = ( Main.data.parsedData | filterByDateRange | filter: Main.tableConfig.generalSearch | orderBy: ['Date', 'Name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
<td ng-repeat="column in Main.tableConfig.columnsConfig | selectColumnsByGranularity: Main.tableConfig.programGranularity">
<span ng-if="!column.isDate" ng-bind="item[column.dataValue] | ifEmpty: 0"></span>
<span ng-if="column.isDate" ng-bind="item[column.dataValue] | date:'MM/dd/yyyy': 'UTC' | ifEmpty: 0"></span>
</td>
</tr>


I want the same
pagination.filteredData
array to be set by each of the
ngRepeat
directives. However, only the first
ngRepeat
that runs sets the value and no other
ngRepeat
will set it again.

I've tried
ngInit
and initializing an object with
pagination
inside of it, and referencing that in my
ngRepeat
. I have also tried using
$parent.pagination.filteredData
.

Using AngularJS v1.5.0

How do I get this to work?

Similar to AngularJS service variable not being set inside of ngRepeat but reworded and fundamentally different. Solving the same problem though.

Edit: Refactored to utilize the
controller as
syntax, the problem still persists. To me it seems that when I switch to a different ngRepeat, a new array and reference is created, instead of overwriting the current arrays values.

Answer

Okay, I have spent some time putting together a demo replicating (as best I could) the code that you have provided <-- Broken, and I think I understand your issue. You say "the first ng-repeat that runs sets the value", and I think it's actually the LAST ng-repeat that runs that is setting it. It's not having a problem setting the value, the problem is that all 3 ng-repeats run every time, so it's always the last one that wins.

The reason this happens is because ng-repeat executes BEFORE ng-if for the common case of <element ng-if="item.showMe" ng-repeat="item in Main.items"></element>

That being said, even though your ng-if condition is false, so the <tr> does not get displayed, the ng-repeat has already run, and already set Main.pagination.filteredData

I think your best course of action would be to move your ng-if up one level to the <tbody>. It would look like the following:

WORKING DEMO <-- Working

<table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Data</th>
        <th>Date</th>
      </tr>
    </thead>
    <tbody ng-if="Main.tableConfig.programGranularity == 'overall'" >
      <tr ng-repeat="item in Main.pagination.filteredData = (Main.data.overallData | filterByDateRange | orderBy: ['date', 'name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
        <td ng-bind="item.name"></td>
        <td ng-bind="item.overall"></td>
        <td ng-bind="item.date"></td>
      </tr>
    </tbody>
    <tbody ng-if="Main.tableConfig.programGranularity == 'team'" >
      <tr ng-repeat="item in Main.pagination.filteredData = (Main.data.teamData | filterByDateRange | orderBy: ['date', 'name']) | startFrom: Main.pagination.startAtIndex | limitTo: Main.pagination.pageSize">
        <td ng-bind="item.name"></td>
        <td ng-bind="item.team"></td>
        <td ng-bind="item.date"></td>
      </tr>
    </tbody>
</table>
Comments