Ruft ein bestimmtes Objekt anhand seiner ID aus einem Array von Objekten in AngularJS ab

111

Ich habe eine JSON-Datei mit einigen Daten, auf die ich auf meiner AngularJS-Website zugreifen möchte. Jetzt möchte ich nur ein Objekt aus dem Array holen. So möchte ich zum Beispiel Artikel mit ID 1.

Die Daten sehen folgendermaßen aus:

{ "results": [
    {
        "id": 1,
        "name": "Test"
    },
    {
        "id": 2,
        "name": "Beispiel"
    },
    {
        "id": 3,
        "name": "Sample"
    }
] }

Ich möchte die Daten mit der folgenden AngularJS $ http-Funktionalität laden:

$http.get("data/SampleData.json");

was funktioniert. Aber wie kann ich jetzt ein bestimmtes Datenobjekt (nach ID) aus dem Array abrufen, von dem ich es erhalte $http.get?

Vielen Dank im Voraus für Ihre Hilfe.

Grüße Marc

mooonli
quelle
Hast du es selbst ausprobiert? Wenn ja, können wir sehen, was Sie sich ausgedacht haben?
Simonlchilds
1
Nun, ich habe keine Ahnung, welcher Weg mit AngularJS am besten wäre. Was ich nicht mag, ist, über das Array zu iterieren und die ID gleich zu machen. Vielleicht gibt es einen besseren Weg?
Mooonli
Sie sollten sich für eine solche Verarbeitung auf Unterstriche oder ähnliche Bibliotheken verlassen. AngularJS ist ein MVVM-Framework und hat möglicherweise keine API dafür.
Vijay Pande
@marcbaur - Sie müssen das Array iterieren. Selbst wenn Sie einen Unterstrich oder ähnliches verwenden, werden die Funktionen hinter den Kulissen nur wiederholt.
Adam
1
Bitte fügen Sie einen
Winkelcode

Antworten:

4

Die einzige Möglichkeit, dies zu tun, besteht darin, über das Array zu iterieren. Wenn Sie sicher sind, dass die Ergebnisse nach ID sortiert sind, können Sie natürlich eine binäre Suche durchführen

Antonio E.
quelle
46
... Ich hoffe wirklich, dass die Leute nach dem Lesen dieser Antwort nicht der Meinung sind, dass es eine gute Idee ist, ein Array zu sortieren und dann eine binäre Suche durchzuführen. Die binäre Suche ist sicher clever , aber nur, wenn das Array bereits sortiert ist. In Wirklichkeit ist es: 1. leicht schlecht zu implementieren, 2. schwerer zu lesen, wenn schlecht implementiert.
Ben Lesh
4
Ich würde mich sehr freuen, wenn die Downvoter ihre Entscheidung motivieren könnten.
Antonio E.
1
Standardmäßig hat der Javascript-Array-Typ die Methode find (). Die find () -Methode gibt den Wert des ersten Elements im Array zurück, das die bereitgestellte Testfunktion erfüllt.
Abosancic
246

Verwenden der ES6-Lösung

Für diejenigen, die diese Antwort noch lesen, wurde die findMethode in Arrays hinzugefügt , wenn Sie ES6 verwenden. Unter der Annahme derselben Sammlung wäre die Lösung:

const foo = { "results": [
    {
        "id": 12,
        "name": "Test"
    },
    {
        "id": 2,
        "name": "Beispiel"
    },
    {
        "id": 3,
        "name": "Sample"
    }
] };
foo.results.find(item => item.id === 2)

Ich würde mich jetzt voll und ganz für diese Lösung entscheiden, da sie weniger an eckige oder andere Rahmenbedingungen gebunden ist. Reines Javascript.

Winkellösung (alte Lösung)

Ich wollte dieses Problem folgendermaßen lösen:

$filter('filter')(foo.results, {id: 1})[0];

Ein Anwendungsfallbeispiel:

app.controller('FooCtrl', ['$filter', function($filter) {
    var foo = { "results": [
        {
            "id": 12,
            "name": "Test"
        },
        {
            "id": 2,
            "name": "Beispiel"
        },
        {
            "id": 3,
            "name": "Sample"
        }
    ] };

    // We filter the array by id, the result is an array
    // so we select the element 0

    single_object = $filter('filter')(foo.results, function (d) {return d.id === 2;})[0];

    // If you want to see the result, just check the log
    console.log(single_object);
}]);

Plunker: http://plnkr.co/edit/5E7FYqNNqDuqFBlyDqRh?p=preview

Willemoes
quelle
1
Eigentlich würde ich denken, dass es das tut! Nach dem Abrufen des Arrays können Sie mit der Funktion $ filter das Element mit der richtigen ID herausfiltern.
Flup
10
Dies sollte die akzeptierte Antwort sein. Ich hatte die gleiche Frage im Kopf und diese Antwort ist die einzige, die vorhandenes AngularJS verwendet und das Rad nicht neu erfindet. Und ja, es funktioniert.
Zoran P.
4
+1 dafür ist die akzeptierte Antwort. Beste Lösung mit Winkelbibliotheken.
Meki
1
Plunker mit Filter in einem Ausdruck: plnkr.co/edit/yc0uZejGqWTcUVKvI7Tq?p=preview
Aaron Roller
4
Beachten Sie, dass Filter standardmäßig Teilzeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung finden. Also (foo.results, {id: 2}) gibt [{id: 12}, {id: 2}], {id: 222}] zurück, aber (foo.results, Funktion (d) {return d.id == = 2;}) gibt [{id: 2}] zurück
Ryan.lay
26

Für alle, die sich diesen alten Beitrag ansehen, ist dies derzeit der einfachste Weg, dies zu tun. Es ist nur ein AngularJS erforderlich $filter. Es ist wie Willemoes Antwort, aber kürzer und leichter zu verstehen.

{ 
    "results": [
        {
            "id": 1,
            "name": "Test"
        },
        {
            "id": 2,
            "name": "Beispiel"
        },
        {
            "id": 3,
            "name": "Sample"
        }
    ] 
}

var object_by_id = $filter('filter')(foo.results, {id: 2 })[0];
// Returns { id: 2, name: "Beispiel" }

WARNUNG

Wie @mpgn sagt, funktioniert dies nicht richtig . Dies wird mehr Ergebnisse erzielen. Beispiel: Wenn Sie 3 suchen, fängt dies auch 23

Tillman32
quelle
1
auch fangen ID: 24 12 222 2002 etc
mpgn
Ich würde denken, dass [0]dies dazu führen würde, dass es das erste Ergebnis zurückgibt, das es aus der Sammlung findet. Es würde also nur funktionieren, wenn Ihre Sammlung sortiert ist und das gesuchte Objekt das erste ist, das es während seiner Iteration findet. Z.B. Wenn es eine ID: 12 gibt, die vor ID: 2 steht, würde sie ID: 12 zurückgeben.
Roddy von den gefrorenen Erbsen
25

persönlich benutze ich Unterstrich für diese Art von Sachen ... also

a = _.find(results,function(rw){ return rw.id == 2 });

dann wäre "a" die Zeile, die Sie von Ihrem Array wollten, in der die ID gleich 2 war

Jason Boerner
quelle
1
Ich liebe Unterstriche wirklich , aber ist es schlimmer, eine andere JavaScript-Bibliothek zu haben?
Echtfafa
8
Beachten Sie, dass findmöglicherweise mehrere Objekte zurückgegeben werden können. Da wir nur eines wollen, können wir verwenden, findWheredas nur das erste Vorkommen zurückgibt (von dem wir wissen, dass es das einzige Vorkommen ist), z a = _.findWhere(results, {id: 2}).
Gregoltsov
16

Ich möchte nur etwas zu Willemoes Antwort hinzufügen . Der gleiche Code, der direkt in den HTML-Code geschrieben wurde, sieht folgendermaßen aus:

{{(FooController.results | filter : {id: 1})[0].name }}

Angenommen, "Ergebnisse" ist eine Variable Ihres FooControllers und Sie möchten die Eigenschaft "Name" des gefilterten Elements anzeigen.

Ena
quelle
@ Ena-Wie prüfe ich, ob das Filterergebnis nicht null oder undefiniert ist?
Abhijeet
Ich habe diese HTML-Variante verwendet, weil ich sicher war, dass ein Ergebnis vorhanden ist. Ich habe es versucht und wenn es kein Ergebnis gibt, gibt die Konsole keinen Fehler aus, sie lässt einfach den Text leer. Wenn Sie eine Logik ausführen müssen, wenn kein Ergebnis gefunden wird, ist die Antwort von Willemoes (js Code im Controller) meiner Meinung nach der beste Weg. In diesem Beispiel sollten Sie dann in HTML prüfen, ob die Variable single_object null oder undefiniert ist.
Ena
2
{{(FooController.results | filter: {id: 1}) [0] .name}: true} - wenn jemand nach einer genauen Übereinstimmung sucht
George Sharvadze
12

Sie können ng-repeatDaten nur verwenden und auswählen, wenn die Daten mit den gewünschten Daten übereinstimmen. ng-show Beispiel:

 <div ng-repeat="data in res.results" ng-show="data.id==1">
     {{data.name}}
 </div>    
James Kuta Simiyu
quelle
2
Wenn Ihr Array mehr als eine unbedeutende Anzahl von Elementen enthält, entstehen viele unnötige Bereiche, die Ihre Anwendung verlangsamen können.
Der DIMM Reaper
9

Sie können einfach Ihr Array durchlaufen:

var doc = { /* your json */ };

function getById(arr, id) {
    for (var d = 0, len = arr.length; d < len; d += 1) {
        if (arr[d].id === id) {
            return arr[d];
        }
    }
}

var doc_id_2 = getById(doc.results, 2);

Wenn Sie diese chaotischen Schleifen nicht schreiben möchten, können Sie underscore.js oder Lo-Dash verwenden (Beispiel in letzterem):

var doc_id_2 = _.filter(doc.results, {id: 2})[0]
Kamituel
quelle
8

Wenn Sie die Liste der Elemente wie Stadt auf der Grundlage der Status-ID möchten, verwenden Sie

var state_Id = 5;
var items = ($filter('filter')(citylist, {stateId: state_Id }));
Ali Adravi
quelle
7

Leider (es sei denn, ich irre mich) denke ich, dass Sie über das Ergebnisobjekt iterieren müssen.

for(var i = 0; i < results.length; i += 1){
    var result = results[i];
    if(result.id === id){
        return result;
    }
}

Zumindest auf diese Weise bricht es aus der Iteration aus, sobald es die richtige übereinstimmende ID findet.

simonlchilds
quelle
Warum? Haben Sie etwas, um das zu belegen?
Simonlchilds
11
Weißt du was? Ich habe gerade Javascript noch einmal gelesen - die guten Teile, um Ihrem Argument entgegenzuwirken, und ich liege falsch! Während dieser ganzen Zeit habe ich es falsch gemacht! Es hat mir aber noch keine Probleme bereitet ... noch nicht. Ich habe meine Antwort aktualisiert.
Simonlchilds
6

Warum die Situation komplizieren? Dies ist einfach, schreiben Sie eine Funktion wie diese:

function findBySpecField(data, reqField, value, resField) {
    var container = data;
    for (var i = 0; i < container.length; i++) {
        if (container[i][reqField] == value) {
            return(container[i][resField]);
        }
    }
    return '';
}

Anwendungsfall:

var data=[{
            "id": 502100,
            "name": "Bərdə filialı"
        },
        {
            "id": 502122
            "name": "10 saylı filialı"
        },
        {
            "id": 503176
            "name": "5 sayli filialı"
        }]

console.log('Result is  '+findBySpecField(data,'id','502100','name'));

Ausgabe:

Result is Bərdə filialı
Musa
quelle
4
$scope.olkes = [{'id':11, 'name':'---Zəhmət olmasa seçim edin---'},
                {'id':15, 'name':'Türkyə'},
                {'id':45, 'name':'Azərbaycan'},
                {'id':60, 'name':'Rusya'},
                {'id':64, 'name':'Gürcüstan'},
                {'id':65, 'name':'Qazaxıstan'}];

<span>{{(olkes | filter: {id:45})[0].name}}</span>

Ausgabe: Azərbaycan

Celal Muhtar
quelle
2

Wenn Sie können, entwerfen Sie Ihre JSON-Datenstruktur, indem Sie die Array-Indizes als IDs verwenden. Sie können Ihre JSON-Arrays sogar "normalisieren", solange Sie die Array-Indizes problemlos als "Primärschlüssel" und "Fremdschlüssel" verwenden können, beispielsweise als RDBMS. Als solches können Sie in Zukunft sogar so etwas tun:

function getParentById(childID) {
var parentObject = parentArray[childArray[childID].parentID];
return parentObject;
}

Dies ist die Lösung "By Design" . Für Ihren Fall einfach:

var nameToFind = results[idToQuery - 1].name;

Wenn Ihr ID-Format etwa "XX-0001" ist und der Array-Index 0 ist , können Sie natürlich entweder eine Zeichenfolgenmanipulation durchführen, um die ID zuzuordnen. Andernfalls kann nichts dagegen unternommen werden, außer durch den Iterationsansatz.

Antonio Ooi
quelle
2

Ich weiß, dass ich zu spät bin, um zu antworten, aber es ist immer besser, aufzutauchen, als überhaupt nicht aufzutauchen :). ES6 Weg, um es zu bekommen:

$http.get("data/SampleData.json").then(response => {
let id = 'xyz';
let item = response.data.results.find(result => result.id === id);
console.log(item); //your desired item
});
Hitesh Kumar
quelle
2

Der einfache Weg, um (ein) Element aus dem Array anhand der ID abzurufen:

Die find () -Methode gibt den Wert des ersten Elements im Array zurück, das die bereitgestellte Testfunktion erfüllt. Andernfalls wird undefined zurückgegeben.

function isBigEnough(element) {
    return element >= 15;
}

var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130  only one element - first

Sie müssen filter () nicht verwenden und das erste Element xx.filter () [0] abfangen, wie in den obigen Kommentaren

Gleiches gilt für Objekte im Array

var foo = {
"results" : [{
    "id" : 1,
    "name" : "Test"
}, {
    "id" : 2,
    "name" : "Beispiel"
}, {
    "id" : 3,
    "name" : "Sample"
}
]};

var secondElement = foo.results.find(function(item){
    return item.id == 2;
});

var json = JSON.stringify(secondElement);
console.log(json);

Wenn Sie mehrere IDs haben, verwenden Sie natürlich die filter () -Methode, um alle Objekte abzurufen. Prost

function isBigEnough(element) {
    return element >= 15;
}

var integers = [12, 5, 8, 130, 160, 44];
integers.find(isBigEnough); // 130  only one element - first

var foo = {
"results" : [{
    "id" : 1,
    "name" : "Test"
}, {
    "id" : 2,
    "name" : "Beispiel"
}, {
    "id" : 3,
    "name" : "Sample"
}
]};

var secondElement = foo.results.find(function(item){
    return item.id == 2;
});

var json = JSON.stringify(secondElement);
console.log(json);

abosancic
quelle
0
    projectDetailsController.controller('ProjectDetailsCtrl', function ($scope, $routeParams, $http) {
    $http.get('data/projects.json').success(function(data) {

        $scope.projects = data;
        console.log(data);

        for(var i = 0; i < data.length; i++) {
        $scope.project = data[i];
        if($scope.project.name === $routeParams.projectName) {
            console.log('project-details',$scope.project);
        return $scope.project;
        }
        }

    });
});

Ich bin mir nicht sicher, ob es wirklich gut ist, aber das war hilfreich für mich. Ich musste $ scope verwenden, damit es richtig funktioniert.

Jordy
quelle
0

Verwenden Sie $ timeout und führen Sie eine Funktion aus, um im Array "results" zu suchen

app.controller("Search", function ($scope, $timeout) {
        var foo = { "results": [
          {
             "id": 12,
             "name": "Test"
          },
          {
             "id": 2,
             "name": "Beispiel"
          },
          {
             "id": 3,
            "name": "Sample"
          }
        ] };
        $timeout(function () {
            for (var i = 0; i < foo.results.length; i++) {
                if (foo.results[i].id=== 2) {
                    $scope.name = foo.results[i].name;
                }
            }
        }, 10);

    });
Moein Fazeli
quelle
0

Ich würde das Ergebnisarray mit einem Winkelfilter wie diesem durchlaufen:

var foundResultObject = getObjectFromResultsList (Ergebnisse, 1);

function getObjectFromResultsList(results, resultIdToRetrieve) {
        return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
    }
oben
quelle