Подтвердить что ты не робот

Удаление элемента AngularJS ngRepeat

Существует несколько вопросов о том, как реализовать удаление элементов внутри директивы ngRepeat, и, как я выяснил, это сводится к использованию ngClick и запускает некоторые функции удаления, передавая ему элемент $индекс.

Однако я не смог найти нигде пример, где у меня есть несколько 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>

Для этого мне нужно будет создать $scope.removePhone и $scope.removeEmail, который будет вызываться с помощью ngClick в разделе "Удалить привязку", Но я ищу более общее решение. Тем более, что у меня много страниц с многими ngRepeats.

Я думал о написании директивы, которая будет помещена в Удалить привязку и будет делать что-то вроде этого:

  • Найдите ngRepeat среди родительских элементов.
  • Прочитайте, что он итерирует ( "user.emails" в первом случае, "user.phones" второй)
  • Удалите элемент $index из модели THAT.

Таким образом, разметка будет выглядеть примерно так:

<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>

Я ищу то, что я ищу, и что было бы предпочтительным способом сделать это?

Текущее хакерское решение

Вот как я это делаю сейчас. Он взломан и уродлив, но выполняет свою работу, пока не выясню более красивый способ.

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

И в 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>
4b9b3361

Ответ 1

Вы можете создать общий метод удаления, который будет принимать в массиве и элемент для удаления.

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

Ответ 2

Нет 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>

Ответ 3

<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>

Ответ 4

Если вы использовали ng-repeat для объекта вместо массива, выполните следующие действия.

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

или более кратким

<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>

предполагает, что объекты выглядят так:

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

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

Ответ 5

Очень простой и удобный способ работы с кросс-браузером - использовать утилиту 'remove' из библиотеки lodash.

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

В вашем контроллере вы объявляете тогда

//inject lodash dependency

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

Вы можете, конечно, использовать индексы, если хотите. См. https://lodash.com/docs#remove