2016-03-29 4 views
0

Ich habe ein Array von Objekten und jedes Objekt hat eine E-Mail-Absender-Eigenschaft wie meine sender{[email protected]}. Jetzt möchte ich eine Tabelle mit 2 Werten füllen: 1) Name ("mein Absender") und 2) Adresse ("[email protected]").AngularJS Filter/Eigenschaft zum Objekt hinzufügen

Momentan verwende ich einen Filter, um meinem Objekt die 2 neuen Eigenschaften hinzuzufügen und es mit einer ng-Wiederholung zu rendern. Mein Problem ist jetzt, dass ich einen Fehler

[$ rootScope: infdig]

(aber Ergebnis Rendering ist in Ordnung). Ich habe ein wenig gegoogelt und das Problem könnte sein, dass ich ein neues Array in meinem Filter erstelle und die Länge der Eigenschaft nicht mit der Objektlänge von ng-repeat übereinstimmt.

Ich bin neu bei angularjs und ich bin mir nicht sicher, ob ich den Filter völlig falsch benutze und es gibt einen viel besseren Weg für meine gesuchte Lösung?

Demo-Code JS:

demoApp.filter("customFilter", function() { 
return function (input) { 
    var result = []; 
    if (input && input.length && input.length > 0) { 
     for (var i = 0; i < input.length; i++) { 
      var senderName = ""; 
      var senderDomain = ""; 
      var both = input[i].Name; 

      both = both.split("").reverse().join(""); 
      senderName = both.substring(both.indexOf("<") + 1).split("").reverse().join(""); 
      senderDomain = both.substring(1, both.indexOf("<")).split("").reverse().join(""); 

      var domainBeforeAt = senderDomain.split("@")[0]; 
      var domainAfterAt = senderDomain.split("@")[1]; 

      var output = { 
       "customId": i, 
       "displayName": senderName, 
       "domain": { 
        "full": senderDomain, 
        "beforeAt": domainBeforeAt, 
        "afterAt": domainAfterAt, 
       } 
      } 

      result.push(output); 
     } 
    } 

    return result;   
} 
}); 

Demo-Code HTML:

<div ng-repeat="sender in list.Sender | customFilter track by $index"> 

Antwort

1

Update: Um die Anforderung für den Zugriff auf verschachtelte Objekte im Filter gerecht zu werden, habe ich die Art und Weise geändert, um die Filter gibt die Ausgabe zurück.

.filter("customFilter", function() { 
    return function (input, params) { 
    ... 
    var args = Array.prototype.slice.call(arguments); 
    var toReturn = output; 
    for (var i = 1; i < args.length; i++) { 
     toReturn = toReturn[args[i]]; 
    } 
    return toReturn; 
}; 
}); 

Ohne eval, output.domain.full zurückkehren, werden Sie in den Ebenen der verschachtelten Objekt als Parameter an die Filter, zB passieren müssen:

<td class="col-xs-6">{{sender.Name | customFilter:'domain':'full'}}</td> 

Also, ich glaube, Ihr Problem Stielen aus der Tatsache, dass Sie nach $ index in Ihrer ng-Wiederholung verfolgen möchten, nicht in Ihrem Filter. Sobald Sie die ng-repeat Direktive in Ihrem div eingerichtet haben, was Sie in Ihren Filter übergeben, ist jeder einzelne Absender in Ihrem Datensatz, nicht alle von ihnen in einem Array, so dass Sie keine for-Schleife über den Eingang ausführen müssen .

Ein Ansatz, den ich im folgenden Ausschnitt gemacht habe, besteht darin, den Parameter, den Sie anzeigen möchten (Name, E-Mail), in den Filter zu übernehmen und die Eigenschaft des von Ihrem Filter ausgegebenen Objekts zu erhalten. Ein anderer Ansatz wäre, einen separaten Namen und E-Mail-Filter zu erstellen und sie einzeln anzuwenden, aber Sie würden auf diese Weise viel Code wiederholen.

angular.module('demoApp', []) 
 
.controller('SenderListCtrl', function() { 
 
    var ctrl = this; 
 
    
 
    ctrl.Sender = [ 
 
    { 
 
     Name: "my sender<[email protected]>", 
 
     Age: 21 
 
    }, 
 
    { 
 
     Name: "another sender<[email protected]>", 
 
     Age: 37 
 
    }, 
 
    { 
 
     Name: "yet another sender<[email protected]>", 
 
     Age: 28 
 
    } 
 
    ]; 
 
}) 
 
.filter("customFilter", function() { 
 
    return function (input, params) { 
 
    
 
    if (input && input.length && input.length > 0) { 
 
     var senderName = ""; 
 
     var senderDomain = ""; 
 
     var both = input; 
 
     
 
     senderName = both.substring(0, both.indexOf("<")); 
 
     senderDomain = both.substring(both.indexOf("<")+1,both.indexOf(">")); 
 
    
 
     var domainBeforeAt = senderDomain.split("@")[0]; 
 
     var domainAfterAt = senderDomain.split("@")[1]; 
 
     var output = { 
 
     name: senderName, 
 
     email: senderDomain, 
 
     domain: { 
 
      full: senderDomain, 
 
      beforeAt: domainBeforeAt, 
 
      afterAt: domainAfterAt, 
 
     } 
 
     }; 
 
     var args = Array.prototype.slice.call(arguments); 
 
     var toReturn = output; 
 
     for (var i = 1; i < args.length; i++) { 
 
     toReturn = toReturn[args[i]]; 
 
     } 
 
     return toReturn;  
 
    }; 
 
    }; 
 
});
<!DOCTYPE html> 
 
<html ng-app="demoApp"> 
 

 
    <head> 
 
    <link data-require="[email protected]" data-semver="3.3.6" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.css" /> 
 
    <script data-require="[email protected]" data-semver="1.5.0" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.js"></script> 
 
    <script data-require="[email protected]" data-semver="3.3.6" src="bootstrap-js"></script> 
 
    <script src="script.js"></script> 
 
    </head> 
 

 
    <body ng-controller="SenderListCtrl as list"> 
 
    <table> 
 
     <thead> 
 
     <tr> 
 
      <th class="col-xs-6">Name</th> 
 
      <th class="col-xs-6">Email</th> 
 
     </tr> 
 
     </thead> 
 
     <tbody> 
 
     <tr ng-repeat="sender in list.Sender track by $index"> 
 
      <td class="col-xs-6">{{sender.Name | customFilter:'name'}}</td> 
 
      <td class="col-xs-6">{{sender.Name | customFilter:'domain':'full'}}</td> 
 
     </tr> 
 
     </tbody> 
 
    </table> 
 
    </body> 
 

 
</html>

Prost!

+0

Ja, das ist die richtige Richtung - danke! :) kann ich {{sender.Name | customFilter: 'domain.full'}} ohne eine Bewertung in meinem Filter? (return eval ("output." param);) – Chris

+1

Gut, dass es geholfen hat! Bitte beachten Sie mein Update bezüglich verschachtelter Parameter. –

Verwandte Themen