У Angular мені потрібно шукати об’єкти в масиві


114

У Angular у мене є об'єкт, який повертає безліч об'єктів. У кожного є ідентифікатор (він зберігається у плоскому файлі, тому немає БД, і я, здається, не можу користувач 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-повторенні'

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

Якщо є якісь питання, просто дайте мені знати.


Оскільки я новачок у кутовій та javascript, я не отримую значення "+" у "if (+ input [i] .id == + id) {", ви можете, будь ласка, поділитися своїми думками.
Харшавардхан

Ідеальне рішення !!
Аніл Кумар Рам

1
Я думаю, що "+ input [i] .id == + id" переконує, що ви порівнюєте числа. Таким чином, ви можете передати 1 або "1" фільтру $, і він поводитиметься точно так само. Я використовую буквено-цифрові ідентифікатори, тому я змінив його на "input [i] .id === id"
Axel Zehden

211

Ви можете скористатися існуючою службою фільтра $. Я оновив скрипку вище 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 для цього), - скоріше використання цієї послуги фільтра $ було саме те, що мені потрібно!
Боббі

2
Краще відповідь, оскільки це не передбачає написання власних фільтрів.
stevenw00

Чи можете ви додати деталі, що $scope.selectedє / що містить. Швидкий пошук по вибраному я знайшов ng-selected/ ngSelected : If the expression is truthy, then special attribute "selected" will be set on the element . Це те саме? У вашому прикладі що це робить? Спасибі
surfmuggle

1
Дивовижно !. Це робить його простим. Спасибі
Бхарат

2
Не забудьте додати службу фільтра $ до свого контролера. тобто: app.controller ('mainController', ['$ filter', функція ($ filter) {// $ filter тепер може використовуватися.}]);
Лукас Реппе Веландер

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 ++ є багато риби. (О, заткнись. Я піду і проголосую сам! !!)
Майк Гледхілл


7

Ваші рішення правильні, але непотрібні складні. Ви можете використовувати функцію чистого фільтра javascript . Це ваша модель:

     $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

Побачив цю тему, але я хотів шукати ідентифікатори, які не відповідали моєму пошуку. Код для цього:

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

Це працювало для мене. Простий, гладкий, легкий для тестування. Дякую!
Калпеш Панчал
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.