AngularJS — ng-повтор не работает с записью карты с именем length и значением 0

#angularjs #nested #angularjs-ng-repeat #ng-repeat

#angularjs #вложенный #angularjs-ng-repeat #ng-repeat

Вопрос:

Я хотел бы показывать события с вложенными событиями, которые я получил от API, в виде JSON

 [
{
"class":"de.ff.prg.EventItem",
"id":27667,
"additional_info":null,
"comments":null,
"event":{"class":"Event","id":27657},
"length":0,
"runningorder":0,
"screening":{"class":"Screening","id":27529},
"title_eng":"'71",
"title_ger":"'71",
"venue":{"class":"Venue","id":1}},

{"class":"de.ff.prg.EventItem",
"id":27676,
"additional_info":null,
"comments":null,
"event":{"class":"Event","id":27657},
"length":5,
"runningorder":0,
"screening":null,
"title_eng":"NEW",
"title_ger":"NEW",
"venue":{"class":"Venue","id":8}
}
] 
  

Чтобы отображать поля элементов в строках, а не в столбцах, я вложил две таблицы с помощью ng-repeat, чтобы получить таблицу таблиц.

 <!--Items-->
<table>
    <thead>
        <td colspan="6" style="background-color: #b9da73">
            <button class="btnAdd" ng-click="addAndEditEventItem()">Add Item</button>
        </td>
    </thead>
    <tbody>

        <tr ng-repeat="item in eventItems">
            <h1>{{eventItems.length}}</h1>
            <th>

            <table>
                <thead>
                    <td colspan="2" style="background-color: #c0da86">{{item.runningorder}}</td>
                    <td colspan="4" style="background-color: #c0da86">
                        <button class="btnAdd" ng-click="deleteEventItem(item.id)">Delete Item</button>
                    </td>
                </thead>
                <tbody>
                {{item}}
                    <tr ng-repeat="(key,value) in item">
                        <th colspan="2" style="background-color: #ceeca1">{{key}}</th>
                        <th colspan="4" style="font-weight: normal;">{{value}} </th>
                    </tr>
                </tbody>
            </table>

            </th>
        </tr>
    </tbody>
</table>
  

До сих пор это не было проблемой, но где-то по пути я потерял возможность отображать тело первой вложенной таблицы (все остальные строки отображаются нормально). Я вставил {{item}} перед тегом body, и он показывает недостающие данные, так что все в порядке.

Есть идеи? Или вам нужно просмотреть другой код, чтобы сообщить? Я понятия не имею…

Вот скрипка

Комментарии:

1. Для начала ваш HTML неверен, вы пропускаете tr from thead > tr > td , h1 не должны быть дочерними tr , исправьте это и, возможно, сделайте скрипку или плунжер, чтобы получить лучшее изображение

2. Вот скрипка для этого [(моя первая скрипка)] ( jsfiddle.net/j5B2F/1 ) (также добавлено в вопросе)

Ответ №1:

Интересный случай. Опытным путем я обнаружил, что это связано с

 "length":0
  

Только что просмотрел исходный код angular и обнаружил, что он преобразует свойства объекта в repeat в массив, а затем использует его свойство length для итерации по нему.

 ...ngRepeatDirective...
              if (isArrayLike(collection)) {
                collectionKeys = collection;
                trackByIdFn = trackByIdExpFn || trackByIdArrayFn;
              } else {
                trackByIdFn = trackByIdExpFn || trackByIdObjFn;
                // if object, extract keys, sort them and use to determine order of iteration over obj props
                collectionKeys = [];
                for (key in collection) {
                  if (collection.hasOwnProperty(key) amp;amp; key.charAt(0) != '$') {
                    collectionKeys.push(key);
                  }
                }
                collectionKeys.sort();
              }

              arrayLength = collectionKeys.length; <<<--- HERE

              // locate existing items
              length = nextBlockOrder.length = collectionKeys.length; <<<--- AND HERE
  

Так что на самом деле ничего не происходит.

На самом деле похоже на ошибку. Я опубликовал проблему.

Просто попробуйте выполнить итерацию по вашему массиву и изменить имя этого свойства. Нравится:

 for(var i = 0; i < $scope.eventItems.length; i  ){
    $scope.eventItems[i].itemLength = $scope.eventItems[i].length;
    delete $scope.eventItems[i].length;
}
  

Комментарии:

1. Спасибо, я попробую это первым делом завтра

2. Да, я удалил ключ, и он работает. Я также проверил замену значения непосредственно на выходе на стороне сервера. Любое значение, кроме 0, в порядке. Спасибо, что подняли проблему, я буду работать над ней, пока она не будет исправлена.