html - Ng-repetición anidada no funciona en IE8
angularjs loops (2)
No estoy seguro exactamente, pero me enfrenté a un tipo similar de problema en uno de mis proyectos previos donde ''seguimiento por'' en ng-repetición problema fijo. Por favor, verifica agregando
(key, metadata) in littleObject.metadata | groupBy:''index'' track by $index
Espero que esto solucione tu problema.
Tengo una aplicación de una sola página en AngularJS 1.2.28 y estoy luchando para que funcione correctamente en IE8.
En particular, tengo un problema con ng-repeat
s anidado utilizado para mostrar el bigObject
declarado dentro del siguiente MainController
:
angular.module(''singlePageApp'')
.controller(''MainController'',
[''$scope'',
function ($scope) {
$scope.showLittleObjectsList = false;
$scope.bigObject = {
objects: [
{
name: "NAME1",
metadata: [
{index: 0, desc: "metadataQ"},
{index: 0, desc: "metadataF"},
{index: 1, desc: "metadataZ"},
{index: 1, desc: "metadataL"}
]
},
{
name: "NAME2",
metadata: [
{index: 0, desc: "metadataH"},
{index: 0, desc: "metadataX"}
]
},
{
name: "NAME3",
metadata: [
{index: 0, desc: "metadataU"},
{index: 1, desc: "metadataG"},
{index: 2, desc: "metadataS"},
]
},
{
name: "NAME4",
metadata: [
{index: 0, desc: "metadataK"},
{index: 1, desc: "metadataR"},
{index: 1, desc: "metadataW"},
{index: 2, desc: "metadataN"},
{index: 2, desc: "metadataC"}
]
}
]
};
}]);
El fragmento HTML principal es algo así (observe que showLittleObjectsList = false;
en el controlador al principio y se usa solo para mostrar las listas al usuario):
<div ng-repeat="littleObject in bigObject.objects | orderBy:''name'':false">
<div>
<button type="button" class="btn btn-default btn-sm" ng-click="showLittleObjectsList = !showLittleObjectsList">
<span class="glyphicon glyphicon-chevron-right" ng-hide="showLittleObjectsList"></span>
<span class="glyphicon glyphicon-chevron-down" ng-show="showLittleObjectsList"></span>
</button>
<span>{{littleObject.name}}</span>
</div>
<div ng-show="showLittleObjectsList">
<div>
<div ng-include="''path/to/singledata/template.html''"></div>
</div>
</div>
</div>
El template.html
de los datos individuales es algo como esto (el filtro groupBy
pertenece a angular-filter ):
<div ng-repeat="(key, metadata) in littleObject.metadata | groupBy:''index''">
<div ng-show="$first">
<strong>
Metadatum desc
</strong>
</div>
<div ng-repeat="metadatum in metadata">
<div>
{{metadatum.desc}}
</div>
</div>
</div>
Todo este código está funcionando bien en Chrome, Firefox e incluso en IE11, dándome algo como esto (el anterior v
es para caret down, porque showLittleObjectsList = true;
):
v NAME1
________________________________________
| Metadata desc: |
| metadataA |
| metadataF |
| metadataZ |
| metadataL |
|_______________________________________|
v NAME2
________________________________________
| Metadata desc: |
| metadataH |
| metadataX |
|_______________________________________|
v NAME3
________________________________________
| Metadata desc: |
| metadataU |
| metadataG |
| metadataS |
|_______________________________________|
v NAME4
________________________________________
| Metadata desc: |
| metadataK |
| metadataR |
| metadataW |
| metadataN |
| metadataC |
|_______________________________________|
Tristemente en IE8, la ng-repeat
más interna se littleObject
con los primeros metadatos de littleObject
, dándome algo como esto:
v NAME1
________________________________________
| Metadata desc: |
| metadataA |
| metadataF |
| metadataZ |
| metadataL |
|_______________________________________|
v NAME2
________________________________________
| Metadata desc: |
| metadataA |
| metadataF |
| metadataZ |
| metadataL |
|_______________________________________|
v NAME3
________________________________________
| Metadata desc: |
| metadataA |
| metadataF |
| metadataZ |
| metadataL |
|_______________________________________|
v NAME4
________________________________________
| Metadata desc: |
| metadataA |
| metadataF |
| metadataZ |
| metadataL |
|_______________________________________|
¿Cómo puedo hacer que esto funcione en IE8?
pequeño EDIT
Luchando con este problema, traté de no usar ng-include
para singledata/template.html
, sino que brutalmente singledata/template.html
ese parcial en el HTML principal que se ve así ahora:
<div ng-repeat="littleObject in bigObject.objects | orderBy:''name'':false">
<div>
<button type="button" class="btn btn-default btn-sm" ng-click="showLittleObjectsList = !showLittleObjectsList">
<span class="glyphicon glyphicon-chevron-right" ng-hide="showLittleObjectsList"></span>
<span class="glyphicon glyphicon-chevron-down" ng-show="showLittleObjectsList"></span>
</button>
<span>{{littleObject.name}}</span>
</div>
<div ng-show="showLittleObjectsList">
<div>
<div ng-repeat="(key, metadata) in littleObject.metadata | groupBy:''index''">
<div ng-show="$first">
<strong>
Metadatum desc
</strong>
</div>
<div ng-repeat="metadatum in metadata">
<div>
{{metadatum.desc}}
</div>
</div>
</div>
</div>
</div>
</div>
Lamentablemente, esto no resuelve el problema.
EDITAR
Una parte importante del objetivo es mostrar las listas con sus metadata
agrupados por index
. Agregué un código de controlador completo, y eventualmente modifiqué los índices de metadata
para que la agrupación tuviera más sentido.
He visto algo muy similar ocurriendo en el mío, donde estaba agrupando datos y luego usando ng-repeat en ese grupo. Tristemente, la única solución que encontré fue hacer mi propia función que devuelve una lista aplanada.
El problema (creo) es que ie-8 simplemente no es lo suficientemente potente como para mantener la repetición en el alcance y el tiempo de espera, mediante el uso de una función solo realizará el cálculo una vez y así reducirá la potencia de procesamiento en bruto necesaria.
Solo para ayudar, esta es la función de agrupación que creé, la he modificado para que funcione con los datos anteriores, simplemente llame a la función y repita los grupos.
$scope.generateGroups = function(littleObject) {
$scope.groups = [];
var options = [];
littleObject.metadata.forEach(function (item, index) {
var groupIndex = $.inArray(item[''index''], options);
if (groupIndex >= 0) {
$scope.groups[groupIndex].push(item);
} else {
options.push(item[''index'']);
var test = [item];
$scope.groups.push(test);
}
});
$scope.apply();
}