2016-07-07 3 views
2

У меня есть несколько ngRepeats генерировать содержимое таблицы, в зависимости от вида, которое хочет видеть пользователь, для генерации таблицы используется другой ngRepeat. Когда пользователь переключает свое представление, и одно из следующего удаляется из DOM, а другое добавлено, новый ngRepeat не ссылается на тот же массив pagination.filteredData.AngularJs - Ссылка на то же свойство scope из нескольких ngRepeat's

Пример:Main - мой контроллер, используя controller as синтаксис.

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

Я хочу того же pagination.filteredData массив должен быть установлен на каждой из ngRepeat директив. Однако только первый запущенный ngRepeat устанавливает значение, и никакое другое ngRepeat не установит его снова.

Я пробовал ngInit и инициализировал объект с помощью pagination внутри него и ссылаясь на это в моем ngRepeat. Я также пробовал использовать $parent.pagination.filteredData.

Использование AngularJS v1.5.0

Как получить эту работу?

Похож на https://stackoverflow.com/questions/38235907/angularjs-service-variable-not-being-set-inside-of-ngrepeat, но переформулирован и принципиально отличается. Решение этой же проблемы.

Редактировать: Реализован для использования синтаксиса controller as, проблема по-прежнему сохраняется. Мне кажется, что когда я переключаюсь на другой ngRepeat, создается новый массив и ссылка вместо того, чтобы перезаписывать текущие значения массивов.

+0

Я вижу этот вопрос почти каждый день, так и в угловом теге.Вам нужно использовать синтаксис «контроллер как» углов, который позволяет вам быть однозначным в отношении той области, которую вы используете в своих представлениях. Вот фантастическая статья, на которую я всегда ссылаюсь, которая объясняет это очень хорошо: https://toddmotto.com/digging-into-angulars-controller-as-syntax/ – mhodges

+1

Вы пробовали 'ng-init =" pagination.startAtIndex = 0 «'? –

+0

Вы можете фильтровать данные вручную в контроллере, введя '$ filter', задайте результат в свойстве службы, а затем повторите итерацию ng-repeat по предварительно отфильтрованным результатам. – adam0101

ответ

1

Хорошо, я провел некоторое время собираю demo replicating (as best I could) the code that you have provided< - Broken, и я думаю, что я понимаю ваш вопрос. Вы говорите, что «первый ng-repeat, который запускает, устанавливает значение», и я думаю, что на самом деле это работает LAST ng-repeat, который устанавливает его. У него нет проблем с настройкой значения, проблема в том, что все 3 нг-повторы запускаются каждый раз, поэтому он всегда является последним, который выигрывает.

Причина это происходит потому, что нг-повтор выполняет ДО нг-если для общего случая <element ng-if="item.showMe" ng-repeat="item in Main.items"></element>

, как говорится, даже если ваш ng-if условие ложно, поэтому <tr> делает не отображается, ng-repeat уже запущен, и уже установлено Main.pagination.filteredData

Я думаю, что лучше всего действовать, чтобы переместить ng-if на один уровень до <tbody>. Это будет выглядеть следующим образом:

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> 
+0

Это замечательное замечание, спасибо! Вы нашли документацию для этого поведения или решили ее самостоятельно? Вероятно, я бы никогда не подумал об этом. После некоторого раздумья вы правы в том, что последний ng-repeat, который запускает, устанавливает его. Предполагая, что они выполняются в том порядке, в котором они находятся в разметке, последний (коллеги) - это то, на что всегда установлен фильтрованный массив. –

+0

@DouglasGaskell Добро пожаловать! Честно говоря, создание демо для изоляции поведения и отображения значения Main.pagination.filteredData действительно помогло. Я мог видеть, что он всегда попадает в последний список, и, пытаясь понять, почему, я помнил, что ng-repeat выполнялся до ng-if, потому что я все время использую эту функциональность. Наиболее логичным решением было просто переместить его до , чтобы ng-repeat не выполнялся, если ng-if был ложным, а проблема решена! – mhodges

+0

@DouglasGaskell Кроме того, я рад, что вы реорганизовали использование «контроллера как». Несмотря на то, что это не было прямым решением вашей проблемы, я думаю, что это будет полезно в долгосрочной перспективе. Жаль, что больше людей об этом не знают, потому что это действительно лучший способ реализовать контроллеры в ваших представлениях (по различным причинам, перечисленным в статье). – mhodges

Смежные вопросы