2014-11-25 13 views
8

Sto passando in 2 matrici alla mia vista. Vorrei che il mio ciclo annidato visualizzasse solo il valore parent_id corrispondente a parent.id. Per esempio.Elementi di filtro ng ripetizione nidificati angolari che corrispondono al valore genitore

arr1 = {"0":{"id":326,"parent_id":0,"title":"Mellow Mushroom voucher","full_name":"Patrick","message":"The voucher says $10 Voucher; some wording on the printout says, \"This voucher is valid for $20 Pizza\" but my purchase price or amount paid also says $20. Shouldn't that be $10","type":"Deals"}}; 
arr2 = {"0":{"id":327,"parent_id":326,"title":"Re: Mellow Mushroom voucher","full_name":"Patrick Williams","message":"Some message here","type":null}; 

... 
<div data-ng-repeat = "parent in arr1"> 
<span>{{parent.title}}<span> 
    <div data-ng-repeat="child in arr2 | only-show-where-child.parent_id == parent.id"> 
     <li>{{child.body}}</li> 
    </div> 
</div> 

È questo possibile/migliori prassi angolare devo essere filtrando l'oggetto in nodo prima di passare in angolare? Grazie!

+0

sto assumendo arr1 e arr2 sono davvero gli array e non solo gli oggetti, se è così allora si può modifica il tuo codice? Vorrei essere me stesso ma non voglio se questo è in realtà parte del problema. –

+0

Sono oggetti, mi dispiace! Apportate modifiche a ciascun oggetto. – davet

risposta

9

ci sono un paio di modi si potesse fare ... Si potrebbe creare una funzione per restituire solo i bambini:

$scope.getChildren = function(parent) { 
    var children = []; 
    for (var i = 0; i < arr2.length; i++) { 
    if (arr2[i].parent_id == parent.id) { 
     children.push(arr2[i]); 
    } 
    } 
    return children; 
}; 

html:

<div ng-repeat="child in getChildren(parent)"> 

Si potrebbe definire un filtro per fare la stessa cosa:

myApp.filter('children', function() { 
    return function(input, parent) { 
    var children = []; 
    for (var i = 0; i < input.length; i++) { 
     if (input[i].parent_id == parent.id) { 
     children.push(input[i]); 
     } 
    } 
    return children; 
    }; 
}); 

html:

<div ng-repeat="child in arr2|children:parent"> 

Entrambi questi metodi eseguiranno comunque ogni ciclo di digestione. Se hai una lunga lista di elementi vorresti sicuramente migliorare le prestazioni. Penso che il modo migliore sarebbe quello di pre-elaborare quei risultati quando li si ottiene, aggiungendo un array figlio a ciascun oggetto in arr1 con solo i suoi figli (qui usando array.filter invece di for loop e array.forEach):

arr1.forEach(function(parent) { 
    parent.children = arr2.filter(function(value) { 
    return value.parent_id === parent.id; 
    }; 
}); 

poi nel codice HTML si sta già lavorando con il genitore in modo da poter ripetere più la sua proprietà figli:

<div ng-repeat="child in parent.children"> 
+0

Grazie per la tua risposta versatile. Funziona perfettamente! – davet

+0

Signore, sei un vero gioiello! –

0

La soluzione dipende dalla frequenza con cui vengono modificati gli array e da quanto sono grandi gli array.

La soluzione pugno è quella di utilizzare il filtro. Ma in questo caso verrebbe chiamato almeno due volte (per assicurarsi che il risultato sia "stabilizzato" - selezionato gli stessi elementi).

Un'altra soluzione è $watch da soli array originale e preparare la versione "visualizzazione" di esso inietti i bambini lì. Personalmente preferirei il secondo come più esplicito.

Tuttavia, se è possibile riutilizzare il filtro "find-the0child" in altre parti dell'applicazione, è possibile procedere con il primo: AngularJS eseguirà nuovamente il filtro solo dopo la modifica della matrice originale.

Se necessario, posso fornire qui un esempio di implementazione di una di queste opzioni: aggiungere il commento per rispondere.

10

Invece di utilizzare i filtri, lo data-ng-if può ottenere lo stesso risultato.

<div data-ng-repeat="parent in arr1"> 
    <span>{{parent.title}}<span> 
    <div data-ng-repeat="child in arr2" data-ng-if="child.parent_id == parent.id"> 
    <li>{{child.body}}</li> 
    </div> 
</div> 
+0

grazie per la soluzione, modo molto elegante per farlo – Woland

Problemi correlati