AngularJS'de nesne dizisinden kimliğe göre belirli nesneyi alın


111

AngularJS web sitemde erişmek istediğim bazı verileri içeren bir JSON dosyam var. Şimdi istediğim, diziden sadece bir nesne almak. Bu yüzden örneğin id 1 olan Öğe istiyorum.

Veriler şuna benzer:

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

Verileri AngularJS $ http işleviyle şu şekilde yüklemek istiyorum:

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

hangi çalışıyor. Ama şimdi aldığım diziden belirli bir veri nesnesini (id ile) nasıl alabilirim $http.get?

Yardımın için şimdiden teşekkür ederim.

Selamlar Marc


Kendinize bir şans verdiniz mi? Eğer öyleyse, ne bulduğunuzu görebilir miyiz?
simonlchilds

1
AngularJS kullanarak en iyi yolun hangisi olduğuna dair hiçbir fikrim yok. Sevmediğim şey, dizi üzerinde yinelemek ve id'de bir eşittir yapmaktır. Belki daha iyi bir yol vardır?
mooonli

Bu tür işlemler için altçizgi veya benzer kitaplıklara güvenmelisiniz. AngularJS, MVVM çerçevesidir ve bunun için api olmayabilir.
Vijay Pande

@marcbaur - diziyi yinelemelisiniz. Alt çizgi veya benzer bir şey kullansanız bile, perde arkasındaki işlevler sadece yineleniyor.
Adam

1
lütfen bunun için açısal kod ekleyin
Ankush Kondhalkar

Yanıtlar:


4

Bunu yapmanın tek yolu, dizi üzerinde yineleme yapmaktır. Açıkçası, sonuçların id'ye göre sıralandığından eminseniz, ikili arama yapabilirsiniz.


46
... Umarım bu cevabı okuduktan sonra insanlar bir diziyi sıralayıp sonra ikili arama yapmanın iyi bir fikir olduğunu düşünmezler. İkili arama akıllıcadır , elbette, ancak yalnızca dizi halihazırda sıralanmışsa ve gerçekte: 1. Kötü bir şekilde uygulanması kolay, 2. Kötü uygulanmışsa okunması daha zor.
Ben Lesh

4
Olumsuz oy verenler kararlarını motive edebilirlerse çok memnun olurum.
Antonio E.

1
Varsayılan olarak javascript Dizi türünün find () yöntemi vardır. Find () yöntemi, dizide sağlanan test işlevini karşılayan ilk öğenin değerini döndürür.
abosancic

246

ES6 çözümünü kullanma

Hala bu cevabı okuyanlar için find, ES6 kullanıyorsanız, yöntem dizilere eklenmiştir. Aynı koleksiyonu varsayarsak, çözüm şu olur:

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

Açısal veya başka herhangi bir çerçeveye daha az bağlı olduğu için, şimdi bu çözümü tamamen tercih ederim. Saf Javascript.

Açısal çözüm (eski çözüm)

Aşağıdakileri yaparak bu sorunu çözmeyi amaçladım:

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

Bir kullanım örneği örneği:

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


1
Aslında öyle olduğunu düşünüyorum! Diziyi getirdikten sonra, doğru kimliğe sahip öğeyi filtrelemek için $ filter işlevini kullanabilirsiniz.
flup

10
Kabul edilen cevap bu olmalıdır. Kafamda da aynı soru vardı ve bu yanıt, mevcut AngularJS'yi kullanan ve tekerleği yeniden icat etmeyen tek cevap. Ve evet, çalışıyor.
Zoran P.

4
Bunun kabul edilen cevap olduğu için +1. Açısal kitaplıkları kullanarak en iyi çözüm.
Meki

1
Bir ifadede filtreli Plunker
Aaron Roller

4
Filtrelerin varsayılan olarak büyük / küçük harfe duyarlı olmayan alt dizeleri bulduğunu unutmayın. Yani (foo.results, {id: 2}), [{id: 12}, {id: 2}], {id: 222}] döndürür ancak (foo.results, function (d) {return d.id == = 2;}) şunu döndürür: [{id: 2}]
Ryan.lay

26

Bu eski gönderiye bakan herkes için şu anda bunu yapmanın en kolay yolu budur. Yalnızca bir AngularJS gerektirir $filter. Willemoes'un cevabı gibi, ancak daha kısa ve anlaşılması daha kolay.

{ 
    "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" }

UYARI

@Mpgn'nin dediği gibi, bu düzgün çalışmıyor . Bu daha fazla sonuç alacaktır. Örnek: 3'ü aradığınızda bu da 23'ü yakalayacaktır


1
ayrıca catch id: 24 12 222 2002 vb
mpgn

Bunun [0]koleksiyondan bulduğu ilk sonucu döndürmesine neden olacağını düşünürdüm , bu nedenle yalnızca koleksiyonunuz sıralanırsa ve aradığınız nesne yinelemesi sırasında ilk bulduğunda işe yarar. Örneğin. id: 2'den önce gelen bir id: 12 varsa, id: 12'yi döndürür.
Roddy of the Frozen Peas

25

kişisel olarak bu tür şeyler için alt çizgi kullanıyorum ...

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

o zaman "a", kimliğin 2'ye eşit olduğu dizinizden istediğiniz satır olur


1
Ben gerçekten seviyorum , çizgi, ama daha kötü Başka bir JavaScript kütüphanesi olan nedir?
Genuinefafa

8
findPotansiyel olarak birden çok nesne döndürebileceğini unutmayın . Yalnızca birini istediğimizden, findWhereyalnızca ilk geçtiği döndüren (ki bu tek oluşum olduğunu biliyoruz) kullanabiliriz, örn a = _.findWhere(results, {id: 2}).
gregoltsov

16

Willemoes cevabına bir şey eklemek istiyorum . Doğrudan HTML'nin içine yazılan aynı kod şöyle görünecektir:

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

"Sonuçlar" ın FooController'ınızın bir değişkeni olduğunu ve filtrelenen öğenin "name" özelliğini görüntülemek istediğinizi varsayarsak.


@ Ena-Filtrenin sonucunun null veya undefined olmadığını nasıl kontrol edebilirim?
Abhijeet

Bu HTML değişkenini kullandım çünkü bir sonucun var olduğundan emindim. Denedim ve sonuç yoksa konsol herhangi bir hata vermiyorsa, metni boş bırakıyor. Eğer sonuç bulunamazsa biraz mantık yapmanız gerekiyorsa, bence en iyi yol Willemoes cevabıdır (denetleyicideki js kodu). Bu örnekte, single_object değişkeninin null veya undefined olup olmadığını HTML'de kontrol etmelisiniz.
Ena

2
{{(FooController.results | filtre: {id: 1}) [0] .name}: true} - biri tam bir eşleşme arıyorsa
George Sharvadze

12

ng-repeatVerileri yalnızca aradığınızla eşleşirse kullanabilir ve seçebilirsiniz ng-show , örneğin:

 <div ng-repeat="data in res.results" ng-show="data.id==1">
     {{data.name}}
 </div>    

2
Dizinizde önemsiz sayıda öğe varsa, bu, uygulamanızı yavaşlatabilecek çok sayıda gereksiz kapsam yaratacaktır.
The DIMM Reaper

9

Dizinizin üzerinden geçebilirsiniz:

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);

Bu dağınık döngüleri yazmak istemiyorsanız, alt çizgi.js veya Lo-Dash kullanmayı düşünebilirsiniz (ikincisinde örnek):

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

8

Eyalet kimliği temelinde şehir gibi öğelerin listesini istiyorsanız şunu kullanın:

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

7

Ne yazık ki (yanılmıyorsam), sonuçlar nesnesi üzerinde yineleme yapmanız gerektiğini düşünüyorum.

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

En azından bu şekilde, doğru eşleşen kimliği bulur bulmaz yinelemeden çıkacaktır.


Neden? Bunu destekleyecek bir şeyin var mı?
simonlchilds

11
Pekala, biliyor musun ..? Argümanınızı karşı iyi parçalar ve ben - ben sadece yeniden okumak JavaScript gitti duyuyorum yanlış! Bunca zamandır yanlış yapıyorum! Bana herhangi bir sorun çıkarmadı ... henüz. Cevabımı güncelledim.
simonlchilds

6

Durum neden karmaşıklaşıyor? bu basittir, şöyle bir işlev yazın:

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 '';
}

Kullanım Örneği:

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'));

çıktı:

Result is Bərdə filialı

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>

çıktı: Azərbaycan


2

Yapabiliyorsanız, dizi dizinlerini ID'ler olarak kullanarak JSON veri yapınızı tasarlayın. Dizi dizinlerini RDBMS gibi "birincil anahtar" ve "yabancı anahtar" olarak kullanmakta sorun yaşamadığınız sürece JSON dizilerinizi bile "normalleştirebilirsiniz". Bu nedenle, gelecekte böyle bir şey bile yapabilirsiniz:

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

"Tasarım gereği" çözüm budur . Durumunuz için basitçe:

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

Elbette, kimlik biçiminiz dizi indeksi 0 olan "XX-0001" gibi bir şeyse , kimliği eşlemek için bir dizi düzenleme yapabilirsiniz; ya da yineleme yaklaşımı dışında bu konuda hiçbir şey yapılamaz.


2

Cevaplamak için çok geç olduğumu biliyorum ama hiç görünmemek yerine her zaman gelmek daha iyidir :). ES6 elde etmenin yolu:

$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
});

2

İd'ye göre diziden (bir) öğe almanın basit yolu:

Find () yöntemi, dizide sağlanan test işlevini karşılayan ilk öğenin değerini döndürür. Aksi takdirde tanımsız döndürülür.

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

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

filter () kullanmanıza ve yukarıdaki yorumlarda olduğu gibi xx.filter () [0] ilk elemanı yakalamanıza gerek yok

Dizideki nesneler için aynı

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);

Elbette birden fazla kimliğiniz varsa, tüm nesneleri almak için filter () yöntemini kullanın. Şerefe

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);


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;
        }
        }

    });
});

Gerçekten iyi olup olmadığından emin değilim, ama bu benim için yardımcı oldu .. Düzgün çalışması için $ kapsam kullanmam gerekiyordu.


0

$ zaman aşımı kullanın ve "sonuçlar" dizisinde arama yapmak için bir işlev çalıştırın

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);

    });

0

Aşağıdaki gibi bir açısaljs filtresi kullanarak sonuçlar dizisi üzerinde yineleme yapardım:

var foundResultObject = getObjectFromResultsList (sonuçlar, 1);

function getObjectFromResultsList(results, resultIdToRetrieve) {
        return $filter('filter')(results, { id: resultIdToRetrieve }, true)[0];
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.