ใน Angular ฉันต้องการค้นหาวัตถุในอาร์เรย์


114

ใน Angular ฉันมีขอบเขตวัตถุที่ส่งคืนวัตถุจำนวนมาก แต่ละคนมี ID (สิ่งนี้ถูกเก็บไว้ในไฟล์แบบแบนดังนั้นจึงไม่มี DB และดูเหมือนว่าฉันจะใช้ไม่ได้ng-resource)

ในตัวควบคุมของฉัน:

$scope.fish = [
    {category:'freshwater', id:'1', name: 'trout', more:'false'},
    {category:'freshwater', id:'2', name:'bass', more:'false'}
];

ในมุมมองของฉันฉันมีข้อมูลเพิ่มเติมเกี่ยวกับปลาที่ซ่อนอยู่โดยค่าเริ่มต้นที่มีng-showมากขึ้น showdetails(fish.fish_id)แต่เมื่อฉันคลิกแท็บการแสดงที่เรียบง่ายมากขึ้นผมอยากจะเรียกใช้ฟังก์ชัน ฟังก์ชันของฉันจะมีลักษณะดังนี้:

$scope.showdetails = function(fish_id) {  
    var fish = $scope.fish.get({id: fish_id});
    fish.more = true;
}

ตอนนี้ในมุมมองรายละเอียดเพิ่มเติมจะปรากฏขึ้น อย่างไรก็ตามหลังจากค้นหาในเอกสารแล้วฉันไม่สามารถหาวิธีค้นหาfishอาร์เรย์นั้นได้

ดังนั้นฉันจะสอบถามอาร์เรย์ได้อย่างไร และในคอนโซลฉันจะเรียกดีบักเกอร์เพื่อให้ฉันมี$scopeวัตถุที่จะเล่นได้อย่างไร

คำตอบ:


95

ฉันรู้ว่ามันช่วยคุณได้บ้างไหม

นี่คือสิ่งที่ฉันพยายามจำลองให้คุณ

ชำระเงิน jsFiddle;)

http://jsfiddle.net/migontech/gbW8Z/5/

สร้างตัวกรองที่คุณสามารถใช้ใน 'ng-repeat'

app.filter('getById', function() {
  return function(input, id) {
    var i=0, len=input.length;
    for (; i<len; i++) {
      if (+input[i].id == +id) {
        return input[i];
      }
    }
    return null;
  }
});

การใช้งานในคอนโทรลเลอร์:

app.controller('SomeController', ['$scope', '$filter', function($scope, $filter) {
     $scope.fish = [{category:'freshwater', id:'1', name: 'trout', more:'false'},  {category:'freshwater', id:'2', name:'bass', more:'false'}]

     $scope.showdetails = function(fish_id){
         var found = $filter('getById')($scope.fish, fish_id);
         console.log(found);
         $scope.selected = JSON.stringify(found);
     }
}]);

หากมีคำถามใด ๆ โปรดแจ้งให้เราทราบ


เนื่องจากฉันเพิ่งเริ่มใช้ angular และ javascript ฉันไม่เข้าใจความหมายของ '+' ในคำสั่ง "if (+ input [i] .id == + id) {" โปรดแบ่งปันความคิดของคุณ
Harshavardhan

โซลูชั่นที่สมบูรณ์แบบ !!
Anil Kumar Ram

1
ฉันคิดว่า "+ input [i] .id == + id" ทำให้แน่ใจว่าคุณกำลังเปรียบเทียบตัวเลข ดังนั้นคุณสามารถส่ง 1 หรือ '1' ไปยัง $ filter และมันจะทำงานในลักษณะเดียวกัน ฉันใช้รหัสตัวอักษรและตัวเลขดังนั้นฉันจึงเปลี่ยนเป็น "input [i] .id === id"
Axel Zehden

211

คุณสามารถใช้บริการ $ filter ที่มีอยู่ได้ ฉันอัปเดตซอด้านบนhttp://jsfiddle.net/gbW8Z/12/

 $scope.showdetails = function(fish_id) {
     var found = $filter('filter')($scope.fish, {id: fish_id}, true);
     if (found.length) {
         $scope.selected = JSON.stringify(found[0]);
     } else {
         $scope.selected = 'Not found';
     }
 }

เอกสารเชิงมุมอยู่ที่นี่http://docs.angularjs.org/api/ng.filter:filter


2
มีประโยชน์มาก - เมื่อฉันเรียนรู้เชิงมุมฉันตระหนักว่าฉันต้องหยุดคิดฟังก์ชัน jQuery ก่อน (พยายามรับ $ .grep เพื่อทำสิ่งนี้) - แต่การใช้บริการ $ filter นี้เป็นเพียงสิ่งที่ฉันต้องการเท่านั้น!
Bobby

2
ตอบดีกว่าเพราะไม่เกี่ยวข้องกับการเขียนฟิลเตอร์ของคุณเอง
stevenw00

คุณสามารถเพิ่มรายละเอียดสิ่งที่$scope.selectedมีอยู่ ทำการค้นหาอย่างรวดเร็วบน i found ng-selected/ ngSelected ที่ เลือกที่เลือก:If the expression is truthy, then special attribute "selected" will be set on the element . เป็นแบบนี้หรือเปล่า? ในตัวอย่างของคุณมันทำอะไร? ขอบคุณ
surfmuggle

1
สุดยอด!. ทำให้ง่าย ขอบคุณ
Bharath

2
อย่าลืมเพิ่มบริการ $ filter ในคอนโทรลเลอร์ของคุณ เช่น: app.controller ('mainController', ['$ filter', function ($ filter) {// $ filter สามารถใช้งานได้แล้ว}]);
Lucas Reppe Welander

22

หากต้องการเพิ่มคำตอบของ @migontech และกล่าวถึงความคิดเห็นของเขาว่าคุณสามารถ "อาจทำให้เป็นเรื่องธรรมดามากขึ้น" นี่คือวิธีการทำ ด้านล่างนี้จะช่วยให้คุณค้นหาตามคุณสมบัติใด ๆ :

.filter('getByProperty', function() {
    return function(propertyName, propertyValue, collection) {
        var i=0, len=collection.length;
        for (; i<len; i++) {
            if (collection[i][propertyName] == +propertyValue) {
                return collection[i];
            }
        }
        return null;
    }
});

การเรียกตัวกรองจะกลายเป็น:

var found = $filter('getByProperty')('id', fish_id, $scope.fish);

หมายเหตุฉันลบโอเปอเรเตอร์ unary (+) เพื่อให้สามารถจับคู่แบบสตริงได้ ...


เมื่อพิจารณาจากเอกสารระบุว่านี่เป็นกรณีการใช้งานสำหรับ ng-init เท่านั้นฉันจะบอกว่านี่เป็นวิธีเชิงมุมที่จะทำ
bluehallu

ตัวอย่างที่เข้าใจง่ายและมีประโยชน์มาก
rainabba

13

วิธีแก้ปัญหาที่สกปรกและง่ายอาจมีลักษณะดังนี้

$scope.showdetails = function(fish_id) {
    angular.forEach($scope.fish, function(fish, key) {
        fish.more = fish.id == fish_id;
    });
};

5
ทำไมถึงเป็นทางออกที่สกปรก ?
Trialcoder

5
ฉันเดาว่าอาจจะมีบันทึกปลาเป็นพันล้านตัวและเราก็วนลูปทีละตัว
RedactedProfile

6
จะมีบันทึกในภาษาอื่น ๆ อีก ฉันหมายความว่ามีปลามากมายใน C ++ (โอ้หุบปาก.. ฉันจะไปลงคะแนนเอง .. !!)
Mike Gledhill


7

วิธีแก้ปัญหาของคุณถูกต้อง แต่ซับซ้อนโดยไม่จำเป็น คุณสามารถใช้ฟังก์ชั่นจาวาสคริปต์กรองบริสุทธิ์ นี่คือโมเดลของคุณ:

     $scope.fishes = [{category:'freshwater', id:'1', name: 'trout', more:'false'},  {category:'freshwater', id:'2', name:'bass', more:'false'}];

และนี่คือหน้าที่ของคุณ:

     $scope.showdetails = function(fish_id){
         var found = $scope.fishes.filter({id : fish_id});
         return found;
     };

คุณยังสามารถใช้นิพจน์:

     $scope.showdetails = function(fish_id){
         var found = $scope.fishes.filter(function(fish){ return fish.id === fish_id });
         return found;
     };

ข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชันนี้: LINK


4

เห็นกระทู้นี้ แต่ฉันต้องการค้นหา ID ที่ไม่ตรงกับการค้นหาของฉัน รหัสที่ต้องทำ:

found = $filter('filter')($scope.fish, {id: '!fish_id'}, false);

สิ่งนี้ได้ผลสำหรับฉัน ง่ายเนียนและง่ายต่อการทดสอบ ขอบคุณ!
Kalpesh Panchal
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.