web-dev-qa-db-fra.com

AngularJS ng Répéter le retrait de l’élément

Il y a pas mal de questions sur la manière d'implémenter la suppression d'éléments dans la directive ngRepeat, et comme je l'ai compris, l'utilisation de ngClick et le déclenchement d'une fonction remove en passant l'élément $ index.

Cependant, je n'ai pu trouver nulle part un exemple où j'ai plusieurs ngRepeats:

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href>Remove</a>
    </div>

    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href>Remove</a>
    </div>
</div>

Pour cela, il me faudrait créer $ scope.removePhone et $ scope.removeEmail qui serait appelé avec ngClick on Retirer l'ancre . Mais je cherche une solution plus générique. Surtout depuis que j'ai beaucoup de pages avec plusieurs ngRepeats.

Je pensais à écrire une directive qui serait placée sur Retirer l'ancre et ferait quelque chose comme ceci:

  1. Trouvez ngRepeat parmi les éléments parents.
  2. Lisez ce qui se passe dessus ('user.emails' dans le premier cas, 'user.phones' dans le second)
  3. Supprimer $ index élément de QUE modèle.

Le balisage ressemblerait à quelque chose comme ceci:

<div ng-controller="MyController">
    <div ng-repeat="email in user.emails">
        {{ email }} <a href remove-directive="$index">Remove</a>
    </div>

    <div ng-repeat="phone in user.phones">
        {{ phone }} <a href remove-directive="$index">Remove</a>
    </div>
</div>

Est-ce que ce que je recherche est possible et quel serait le moyen préféré de le faire?

Solution actuelle de hacky

Voici comment je le fais actuellement. C'est hacky et moche mais fait le travail jusqu'à ce que je trouve une façon plus jolie.

  myAppModule.controller('MyController', function ($scope, $parse, $routeParams, User) {
    $scope.user = User.get({id: $routeParams.id});

    $scope.remove = function ($index, $event) {
      // TODO: Find a way to make a directive that does this. This is ugly. And probably very wrong.
      var repeatExpr = $($event.currentTarget).closest('[ng-repeat]').attr('ng-repeat');
      var modelPath  = $parse(repeatExpr.split('in')[1].replace(/^\s+|\s+$/g, ''));

      $scope.$eval(modelPath).splice($index, 1);
    };
  });

Et dans les DOM:

<div ng-repeat="email in user.email" class="control-group">
  <label class="control-label">
    {{ "Email Address"|_trans }}
  </label>

  <div class="controls">
    <input type="text" ng-model="email.address">

    <span class="help-inline"><a href ng-click="remove($index, $event)">{{ "Delete"|_trans }}</a></span>
  </div>
</div>
56
user2742648

Vous pouvez créer une méthode de suppression générique prenant le tableau et l'élément à supprimer.

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} <a ng-click="remove(emails, $index)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} <a ng-click="remove(phones, $index)">Remove</a>
    </div>
</div>

$scope.remove = function(array, index){
    array.splice(index, 1);
}
78
Mark Coleman

Pas de JS

<div ng-repeat="option in options" ng-init=options=[1,2,3,4,5]>
   <button ng-click="options.splice($index,1)">Remove me</button>      
</div>
71
Code Whisperer
<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails as datasource">{{ email }} 
        <a ng-click="datasource.splice($index,1)">Remove</a>
    </div>
    <div ng-repeat="phone in phones as datasource">{{ phone }} 
        <a ng-click="datasource.splice($index,1)">Remove</a>
    </div>
</div>
19
Madhu Dhanasekaran

Un moyen très simple et pratique qui fonctionne avec plusieurs navigateurs consiste à utiliser la méthode utilitaire 'remove' de la bibliothèque lodash.

<div ng-repeat="phone in phones">{{ phone }} 
  <a ng-click="removeItem(phones, phone)">Remove</a>
</div>

Dans votre contrôleur, vous déclarez alors

//inject lodash dependency

//declare method in scope
$scope.removeItem = function(list, item){
   lodash.remove(list,function(someItem) { return item === someItem});
}

Vous pouvez bien sûr utiliser des index si vous le souhaitez. Voir https://lodash.com/docs#remove

3
Igor Lino

Si vous avez utilisé ng-repeat sur un objet au lieu d'un tableau, procédez comme suit.

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="remove(emails, email)">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="remove(phones, phone)">Remove</a>
    </div>
</div>

$scope.remove = function(objects, o){
    delete object[o.id];
}

ou le plus laconique

<div ng-app="" ng-controller="MyController">
    <div ng-repeat="email in emails">{{ email }} 
      <a ng-click="delete emails[email.id]">Remove</a>
    </div>
    <div ng-repeat="phone in phones">{{ phone }} 
      <a ng-click="delete phones[phone.id]">Remove</a>
    </div>
</div>

suppose que les objets ressemblent à ceci

var emails = {  '123' : { id : '123', .... }  };

var phones = {  '123' : { id : '123', .... }  };
1
Tom Carchrae