Angularjs использует ng-if для выборочного ng-repeat

У меня есть следующие массивы:

$scope.selected_items = [
    {id: "12345"},
    {id: "67890"}
]

$scope.list_items = [
    { id: "12345", name: "first", more: "data" },
    { id: "22222", name: "second", more: "data2" },
    { id: "33333", name: "third", more: "data3" },
]

Я пытаюсь перечислить все элементы в $scope.list_items, чьи id отсутствуют в $scope.selected_items. Я знаю, что мне нужно что-то сделать с ng-if, но я не могу понять, что делать.

<div ng-repeat="data in list_items" ng-if="????">
    {{ data.name }}
</div>

Может ли кто-нибудь помочь мне разобраться с этой проблемой?


person bryan    schedule 14.05.2015    source источник


Ответы (4)


Я предлагаю хранить информацию, если объект выбран внутри самого массива.

e.g.:

JavaScript

$scope.list_items = [
    { id: "12345", name: "first", more: "data", selected: true },
    { id: "22222", name: "second", more: "data2" },
    { id: "33333", name: "third", more: "data3" selected: true },
]

HTML

<div ng-repeat="data in list_items | filter:{selected:false}">
    {{ data.name }}
</div>
person Roger Ramos    schedule 14.05.2015
comment
Или почему бы просто не использовать ng-repeat="data in list_items | filter:{selected: false}" или использовать negated и избегать ng-show - person PSL; 15.05.2015
comment
Спасибо, Роджер. Я изменил свой код, чтобы работать с этим. Я ценю быстрый ответ. Что эффективнее @PSL? ng-if, filter или ng-show - person bryan; 15.05.2015
comment
@bryan Наиболее эффективным было бы выполнить фильтрацию в вашем контроллере (сохранить отфильтрованный список, привязать его к DOM и обновить отфильтрованный список при выборе элемента) ... чтобы выражение не оценивалось каждый цикл дайджеста. то есть $scope.filtered = $scope.list_items.filter(function(itm){return !itm.selected}). Если вы используете фильтр в DOM, ng-if, ng-show, все они создают наблюдателя. - person PSL; 15.05.2015

Поскольку вы упомянули, вы не можете сохранить выбранное состояние в самом массиве list_items. вы, вероятно, можете вызвать функцию в ng-if и проверить, существует ли элемент в выбранном, используя функцию.

<div ng-repeat="data in list_items" ng-if="checkItem(data)">
    {{ data.name }}
  </div>

Функция будет выглядеть так,

$scope.checkItem = function(item)
  {
    for(var i=0;i<$scope.selected_items.length;i++)
    {
      var sItem = $scope.selected_items[i];
      if(sItem.id===item.id)
        return false;
    }
    return true;
  }

ссылка plnkr http://plnkr.co/edit/3a4zoKIKFABAmif0fKFt?p=preview

person Kathir    schedule 14.05.2015
comment
Спасибо за работу вокруг Kathir. Я обязательно буду иметь это в виду, но похоже, что выбранный тег был более эффективным, поэтому я изменил свой код. - person bryan; 15.05.2015
comment
Я согласен, что это эффективный способ. - person Kathir; 15.05.2015

Если он должен быть разделен, как в вашем примере, лучше всего создать новый массив с элементами, которые вы хотите повторить.

Итак, вы бы сделали что-то подобное:

$scope.newList = [];
for (var i=0; $scope.list_items.length < i; i++) {
  for (var s=0; $scope.selected_items.length < s; s++) {
    if ($scope.selected_items[s].id == $scope.list_items[i].id) {
       $scope.newList.push($scope.list_items[i]);
    }
}

Было бы идеально сделать то, что сказал парень выше меня, сохранить все это в одном объекте и просто иметь там флаг display: true/false.

person Speedy059    schedule 14.05.2015

Что ж, правильным шаблоном было бы использование фильтра AngularJS.

Вы просто добавляете фильтр в свой ngRepeat:

myApp.filter('selectedItems', function () {
    return function (values, selectedItemsArr) {
        console.log(values, selectedItemsArr)

        var arrayToReturn = [];
        // Loops through the values in the list
        for (var i = 0; i < values.length; i++) {

            // Now loops through the selected items array to see if it matches
            for (var l = 0; l < selectedItemsArr.length; l++) {
                 if (values[i].id === selectedItemsArr[l].id) {
                    arrayToReturn.push(values[i]);
                }
            }
        }

        return arrayToReturn;
    };
});

Пример здесь: http://jsfiddle.net/Nitrium/3vcs445c/1/

person Giliar Perez    schedule 14.05.2015