2

I have the following arrays:

$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" },
]

I am trying to list out all the items in $scope.list_items who's id is not present in $scope.selected_items. I know I have to do something with ng-if but I can't figure out what to do.

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

Could anyone help me figure out this problem?

bryan
  • 8,879
  • 18
  • 83
  • 166

4 Answers4

2

I suggest storing information if the object is selected within the array itself.

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>
Roger Ramos
  • 568
  • 8
  • 22
  • 1
    Or why not just `ng-repeat="data in list_items | filter:{selected: false}"` or use [negated](http://stackoverflow.com/questions/13278371/angularjs-filter-negated) and avoid a ng-show – PSL May 14 '15 at 21:30
  • Thanks Roger. I modified my code to work with this. I appreciate the fast answer. What's more efficient @PSL? `ng-if`, `filter`, or `ng-show` – bryan May 14 '15 at 21:30
  • 1
    @bryan Most efficient would be to do the filtering in your controller (keep a filtered list and bind it to DOM and update the filtered list when you select an item)... so that expresion does not get evaluated every digest cycle. i.e `$scope.filtered = $scope.list_items.filter(function(itm){return !itm.selected})`. If you use filter on the DOM, ng-if, ng-show they all create a watcher. – PSL May 14 '15 at 21:32
1

Since you mentioned you cant keep the selected state in the list_items array itself. you can probably call a function in the ng-if and check whether the item exists in the selected using a function.

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

The function will look like this,

$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 link http://plnkr.co/edit/3a4zoKIKFABAmif0fKFt?p=preview

Kathir
  • 6,136
  • 8
  • 36
  • 67
  • Thanks for the work around Kathir. I will definitely keep this in mind but it looks like the selected tag was more efficient so I modified my code. – bryan May 14 '15 at 21:30
  • I would agree thats the efficient way. – Kathir May 14 '15 at 21:33
1

If it must be separated as in your example, you best bet is to create a new array with the items you want to ng-repeat.

So what you would do is something similar:

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

It would be ideal to do what the guy above me said, keep all of this in one object and just have a display: true/false flag in there.

Speedy059
  • 629
  • 10
  • 24
1

Well, the correct pattern would be to use a AngularJS filter.

You just add the filter to your 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;
    };
});

Example here: http://jsfiddle.net/Nitrium/3vcs445c/1/

Giliar Perez
  • 106
  • 2