0

I am trying to use Angular to manage a list of Tags through an interface.

I have a server-pulled list of Tags in my scope.

app.js

$scope.Tags = [{id:1, name:'tag1', desc:'desc1'}, {id:2, name:'tag2', desc:'desc2'}, {id:3, name:'tag3', desc:'desc1'}, ...];

and I display the list using this chunk of html code :

tags.html

<ul>
 <li ng-repeat="T in Tags">{{ T.name }}</li>
</ul>

When I click on the <li> element I want angular to remove the associated Tag object. Then I enhance my code as follow :

tags.html

<ul>
 <li
    ng-repeat="T in Tags"
    ng-click="removeTag($event);"
 >{{ T.name }}</li>
</ul>

app.js

$scope.removeTag = function (event) {

  // the following code is just used to remove the Tag from the list
  // using underscore.js

  $scope.Tags = _($scope.Tags).filter(function (t) {
   return t.name !== event.srcElement.innerHTML
  });
}

This is working, but I wish there were a lighter way to perform the same task. And my experience of Angular is still limited.

Something like that would be great :

<ul>
  <li ng-repeat="T in Tags" ng-click="Tags - T">{{ T.name }}</li>
  <!-- this is more like a dream tho -->
</ul>
0

3 Answers 3

1

Try splicing the array based on the index in the array ($index), like this:

<ul>
  <li ng-repeat="T in Tags" ng-click="Tags.splice($index, 1)">{{T.name}}</li>
</ul>
Sign up to request clarification or add additional context in comments.

6 Comments

this surprisly works. is there some downsides as proceeding this way ?
@발렌텐 - The only downside is if you have other logic to run other than simply removing the element from the array (like calling a server-side API).
@JustinNiessner I aint have, then I guess there is nothing wrong in using this syntax. I love it
@발렌텐 - You may also run into issues if you allow sorting/filtering of the data.
Your HTML may look a little cleaner (just ng-click="removeTag($index)") if you move the splicing into a function within your controller...but it works either way. If you like $index, be sure to look into $first and $last as they can come in handy as well (not necessarily for your current use case, but good to know nonetheless).
|
0

The click event handler should be like this:

<ul>
 <li
    ng-repeat="T in Tags"
    ng-click="removeTag(T);"
 >{{ T.name }}</li>
</ul>

In your controller:

$scope.removeTag = function (t) {
   $scope.Tags.splice($scope.Tags.indexOf(t),1);
}

Instead of passing the event object, am passing the object itself.

DEMO:

angular.module("app",[])
.controller("MainCtrl", function($scope) {
$scope.Tags = [{id:1, name:'tag1', desc:'desc1'}, {id:2, name:'tag2', desc:'desc2'}, {id:3, name:'tag3', desc:'desc1'}];
$scope.removeTag = function (t) {
   $scope.Tags.splice($scope.Tags.indexOf(t),1);
}
});
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.2/angular.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body ng-controller="MainCtrl">
<ul>
 <li
ng-repeat="T in Tags"
ng-click="removeTag(T);"
 >{{ T.name }}</li>
</ul>
</body>
</html>

Comments

0

There is no "Angular" way to remove an item from an array. You just need to do it the regular old JavaScript way. There are also some easy changes you can make to make your code cleaner. First, change your markup to:

<ul>
    <!-- Pass the Tag, not the event -->
    <li ng-repeat='T in Tags' ng-click='removeTag(T)'>
        {{ T.name }}
    </li>
</ul>

And then remove can become:

$scope.removeTag = function(tag) {
  var index = $scope.Tags.indexOf(tag);
  if(index > -1) $scope.Tags.splice(index, 1);
}

1 Comment

I think you mean to use splice, not slice

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.