2017-04-07 4 views
0

Ich möchte Tabelle mit Filtern in Tabellenheader erstellen. Filter ist eine Liste eindeutiger Werte in jeder Spalte. Hier wird vereinfacht Code:

<table> 
    <tr> 
     <th class="dropdown" ng-repeat="field in data.columns"> 
     <span>{{field.title}}</span> 
     <ul class="dropdown-menu"> 
      <li ng-repeat="item in unique(data.items, field)"><checkbox> {{item.text}}</li> 
     </ul> 
     </th> 
    </tr> 
    <tr ng-repeat="item in data.items"></tr> 
</table> 

I verwenden gleichen Objektarray für Filter und Filtertabelle aber erstellen Kopie des Arrays und entfernen von Werten, die Kopie wiederholt. Und hier ist mein Problem.

Wenn ich Array als array.slice(0) kopiert löschte Werte nicht im Filter, sondern auch in der Tabelle (Array enthält Objekte). Mein Problem ist in Referenzen, so habe ich als deep jQuery.extend(true, [], array) und Winkel wirft Fehler:

[$rootScope:infdig] 10 $digest() iterations reached. Aborting! Watchers fired in the last 5 iterations

Meine Daten sehen wie folgt aus:

[{id: 1, title: 'AAA', something: [{id: 1, text: "A"}]}, {id: 2, title: 'AAAA', something: [{id: 2, text: "AA"}]}] 

Problem ist in Eigentum etwas (array.slice(0) DonT kopieren und $ .extend Kopie, aber Winkel get Fehler)

Vielen Dank für Ratschläge

+0

'angular.copy()' die Winkel Art und Weise. – Jai

+1

Ich denke, Ihr Problem wird verschwinden, wenn Sie einige der Logik der Manipulation der Arrays auf Ihren Controller verschieben. Versuchen Sie, den Aufruf an unique (data.items, field) zu einer Controller-Funktion zu verschieben. Wenn Sie eine der ng-Wiederholungen reduzieren können, reduziert dies die Anzahl der Digest-Zyklen erheblich. – Matt

+0

Ein anderer winkliger Ansatz könnte die Verwendung von $ filter ('filter') oder das Erstellen eines benutzerdefinierten Filters für die ng-Wiederholung sein. – Matt

Antwort

1

Sie nicht den Code für den Filter gebucht haben, so muss ich ein was ist los? Ich denke, Sie prüfen nicht, ob alle Elemente der Liste eindeutig sind, bevor Sie eine Kopie erstellen. Dies bewirkt, dass der Filter die Daten jeden Digest ändert und eine unendliche Anzahl von Digests auslöst - daher der Fehler. Deine Liste ist niemals stabil.

Um dies am Anfang des Filters zu lösen, addiere die Eindeutigkeit der Elemente und wenn sie bereits eindeutig sind (zum Beispiel nach dem ersten Durchlauf des Filters) gib einfach das Eingabeobjekt zurück. Auf diese Weise wird sich das Modell stabilisieren.

0

Hier ist mein Code für eindeutigen Wert von Objekten Array zu erhalten:

function toUnique(a, property, innerProperty) { 
     var lastIndex = a.length; 
     if (lastIndex === 0 || lastIndex === undefined) 
      return a; 
     var copyarr = jQuery.extend(true, [], a); 
     if (property !== undefined) { 
      while (prevIndex = --lastIndex) { 
       while (prevIndex--) { 
        var obj1 = copyarr[lastIndex]; 
        var obj2 = copyarr[prevIndex]; 

        if (obj1 !== undefined) { 
         if (copyarr[lastIndex][property] instanceof Array && copyarr[prevIndex][property] instanceof Array) 
          unique(copyarr[lastIndex][property], copyarr[prevIndex][property], innerProperty); 
         else 
          obj1[property] !== obj2[property] || copyarr.splice(prevIndex, 1); 
        } 
       } 
      } 
      return copyarr; 
     } else { 
      while (prevIndex = --lastIndex) 
       while (prevIndex--) 
        copyarr[lastIndex] !== copyarr[prevIndex] || copyarr.splice(prevIndex, 1); 
      return copyarr; 
     } 
    } 

function unique(array1, array2, innerProperty) { 
    for (var i = 0; i < array1.length; i++) { 
     removeDuplicates(array1, i + 1, array1[i], innerProperty); 
     removeDuplicates(array2, 0, array1[i], innerProperty); 
    } 
    for (var i = 0; i < array2.length; i++) { 
     removeDuplicates(array2, i + 1, array2[i], innerProperty); 
    } 
} 

function removeDuplicates(arr, startPos, p, property) { 
    for (var i = startPos; i < arr.length;) { 
     if (p[property] == arr[i][property]) { 
      arr.splice(i, 1); 
     } else { 
      i++; 
     } 
    } 
} 

Verwendung:

var a = [{id: 1, title: "AAAA"}, {id: 2, title: "BBBB"}, {id: 1, title: "AAAA"}] 
    unique(a, "title", null); //return {id: 1, title: "AAAA"}, {id: 2, title: "BBBB"} 

    var b = [{id: 1, title: "AAAA", authors: [{id: 15, name: "John"}, {id: 25, name: "Peter"}, {id: 16, name: "John"}]}, 
{id: 1, title: "BBBB", authors: [{id: 15, name: "John"}, {id: 25, name: "Peter}]}] 

    unique(b, "authors", "name") //return: [{id: 1, title: "AAAA", authors: [{id: 15, name: "John"}, {id: 25, name: "Peter}]}, 
{id: 1, title: "BBBB", authors: []}] 
+0

Nachdem Sie 'if (lastIndex === 0 || lastIndex === undefined) überprüft haben, überprüfen Sie auch, ob alle Elemente bereits eindeutig sind, und wenn ja, geben Sie 'a' zurück. Sie können auch Bibliotheken wie 'linq.js' oder' lodash' verwenden, bei denen bereits eine eindeutige Überprüfung implementiert wurde. – Episodex

Verwandte Themen