ng-click을 사용하여 배열에서 항목 또는 객체를 어떻게 삭제합니까?


261

버튼을 클릭 할 때 항목을 제거 할 수있는 기능을 작성하려고하는데 기능과 혼동되고 있다고 생각합니다 $digest. 사용 합니까?

HTML 및 app.js :

<ul ng-repeat="bday in bdays">
  <li>
    <span ng-hide="editing" ng-click="editing = true">{{bday.name}} | {{bday.date}}</span>
    <form ng-show="editing" ng-submit="editing = false">
      <label>Name:</label>
      <input type="text" ng-model="bday.name" placeholder="Name" ng-required/>
      <label>Date:</label>
      <input type="date" ng-model="bday.date" placeholder="Date" ng-required/>
      <br/>
      <button class="btn" type="submit">Save</button>
      <a class="btn" ng-click="remove()">Delete</a>
    </form>
  </li>
</ul>

$scope.remove = function(){
  $scope.newBirthday = $scope.$digest();
};

2
Angular의 다이제스트 루프를 입력하는 데 사용되기 때문에 $ digest를 원하지 않습니다 (그리고 ng-click으로 인해 이미 다이제스트 루프에 있습니다). 배열에서 항목을 제거하려고합니까?
Mark Rajcok

@MarkRajcok :) 그렇습니다 무엇을하려고합니까
Jess McKenzie

remove()ng-click방법 당신은 어떤 상황이 없습니다 있습니다. 제거중인 ng-repeat항목과 제거중인 항목 또는 제거중인 항목 또는 원하는 동작 을 표시하려면 마크 업에 대한 자세한 내용이 필요합니다.remove()
charlietfl

@charlietfl 그것은 ng-repeat 안에 있습니다. 질문을 업데이트했습니다
Jess McKenzie

답변:


551

항목을 제거하려면 배열에서 bday항목을 제거해야하며 마크 업에서 항목을 제거 기능으로 전달할 수 있습니다 . 그런 다음 컨트롤러에서 항목의 색인을 찾아 배열에서 제거하십시오.

<a class="btn" ng-click="remove(item)">Delete</a>

그런 다음 컨트롤러에서 :

$scope.remove = function(item) { 
  var index = $scope.bdays.indexOf(item);
  $scope.bdays.splice(index, 1);     
}

Angular는 bdays배열 변경을 자동으로 감지 하고 업데이트를 수행합니다.ng-repeat

데모 : http://plnkr.co/edit/ZdShIA?p=preview

편집 : 서버로 실시간 업데이트를 수행하면 서버를 $resource업데이트하는 동시에 어레이 업데이트를 관리하기 위해 만든 서비스를 사용 하는 경우


62
$index템플릿을 사용하여 목록을 필터링 하면 직접 사용하면 버그가 발생할 수 있습니다. 템플릿 일입니다. ng-click='remove(bday)'그때 사용하는 것이 더 안전합니다arr.splice(arr.indexOf(bday),1);
Umur Kontacı

6
메소드 내에서 'this'를 사용할 수 있으므로 $ index를 전달할 필요가 없습니다. $ scope.remove = function () {$ scope.bdays.splice (this. $ index, 1); }
matchdav

1
@matthewdavidson this is undefined. Plunker / jsfiddle?
Tjorriemorrie

11
.indexOf(item)찾을 수 없으면 -1을 반환합니다. 확인하지 않으면 배열 끝에서 항목이 제거 될 수 있습니다.
Ben Wilde

1
@ShibinRagh는 대한 문서 읽기 Array.prototype.splice ()
charlietfl

54

이것은 정답입니다.

<a class="btn" ng-click="remove($index)">Delete</a>
$scope.remove=function($index){ 
  $scope.bdays.splice($index,1);     
}

@charlietfl의 답변에서. $index매개 변수로 전달했기 때문에 잘못되었다고 생각 하지만 컨트롤러에서 소원을 대신 사용합니다. 틀 렸으면 말해줘 :)


함수는 $없이 색인을 수락 할 수 있지만 여전히 작동합니다.
svarog

이것이 정답이어야합니다. indexOfIE9 + 인 경우에만 작동
levi

17
ng-repeat에 orderBy 또는 필터가 있으면 작동하지 않습니다.
Joan-Diego Rodriguez

$ index로 트랙을 사용한 경우 더 효과적입니다.
Ankit Balyan

@ Joan-DiegoRodriguez 필터 / 주문이있는 경우 어떻게 작동하게됩니까 XMLilley의 답변을
jamesmstone

26

ng-repeat 안에 있다면

하나의 라이너 옵션을 사용할 수 있습니다

    <div ng-repeat="key in keywords"> 
        <button ng-click="keywords.splice($index, 1)">

            {{key.name}}
        </button>
    </div>

$index 각도에 의해 배열의 현재 색인을 표시하는 데 사용됩니다 ng-repeat


1
나는이 1 개의 강선을 좋아하고 사용했다
etoricky

24

사용 $index기본 경우에 완벽하게 잘 작동하고 @ charlietfl의 대답은 아주 좋습니다. 그러나 때로는 $index충분하지 않습니다.

두 개의 다른 ng-repeat로 표시되는 단일 배열이 있다고 가정하십시오. 이러한 ng-repeat 중 하나는 확실한 속성을 가진 개체에 대해 필터링되고 다른 하나는 거짓 속성에 대해 필터링됩니다. 하나의 원래 배열에서 파생 된 두 개의 서로 다른 필터링 된 배열이 제공됩니다. (또는 시각화하는 데 도움이되는 경우 : 한 명의 사람들이있을 수 있으며 해당 배열의 여성들과 같은 배열 의 남성들에 대한 ng-repeat를 원할 것 입니다.) 목표 : 필터링 된 배열 구성원의 정보를 사용하여 원래 배열.

필터링 된 각 배열에서 $ index는 원래 배열 내 항목의 인덱스가 아닙니다. 필터링 된 subarray 의 인덱스가 됩니다 . 따라서 원래 people배열 에서 사람의 색인을 말할 수 없으며 , women또는 men하위 배열 의 $ index 만 알 수 있습니다. 그것을 사용하여 삭제하려고하면 원하는 곳을 제외한 모든 곳에서 항목이 사라집니다. 무엇을해야합니까?

운이 좋으면 데이터 모델에 각 객체에 대한 고유 식별자가 포함되어 있으면 $ index 대신 식별자를 사용하여 객체와 splice기본 배열 에서 객체를 찾으십시오 . (아래 예제를 사용하지만 고유 식별자를 사용하십시오.) 그러나 운이 좋지 않다면?

Angular는 실제로라는 고유 속성을 사용하여 ng- 반복 배열 (기본, 원래 배열)의 각 항목을 보강합니다 $$hashKey. $$hashKey삭제하려는 항목 과 일치하는 원본 배열을 검색하여 제거 할 수 있습니다.

참고 $$hashKey구현 세부입니다은, 겨 반복에 게시 된 API에 포함되지 않습니다. 그들은 언제든지 그 재산에 대한 지원을 제거 할 수 있습니다. 그러나 아마 아닐 것입니다. :-)

$scope.deleteFilteredItem = function(hashKey, sourceArray){
  angular.forEach(sourceArray, function(obj, index){
    // sourceArray is a reference to the original array passed to ng-repeat, 
    // rather than the filtered version. 
    // 1. compare the target object's hashKey to the current member of the iterable:
    if (obj.$$hashKey === hashKey) {
      // remove the matching item from the array
      sourceArray.splice(index, 1);
      // and exit the loop right away
      return;
    };
  });
}

다음과 같이 호출하십시오.

ng-click="deleteFilteredItem(item.$$hashKey, refToSourceArray)"

편집 : $$hashKey모델 별 속성 이름 대신 키를 입력하는 이와 같은 기능을 사용하면 이 기능을 다른 모델 및 컨텍스트에서 재사용 할 수 있다는 상당한 이점이 있습니다. 배열 참조 및 항목 참조를 제공하면 제대로 작동합니다.


10

나는 보통 그런 스타일로 쓴다 :

<a class="btn" ng-click="remove($index)">Delete</a>


$scope.remove = function(index){
  $scope.[yourArray].splice(index, 1)
};

이것이 $ scope와 [yourArray] 사이에 dot (.)을 사용해야하는 데 도움이되기를 바랍니다.


(인덱스 1)의 "1"의 의미는 무엇입니까
ShibinRagh

@ShibinRagh 그것은 deleteCount입니다. 제거 할 이전 배열 요소 수를 나타내는 정수입니다. deleteCount가 0이면 요소가 제거되지 않습니다. 이 경우 하나 이상의 새 요소를 지정해야합니다. deleteCount가 시작시 시작하여 배열에 남아있는 요소 수보다 크면 배열 끝을 통과하는 모든 요소가 삭제됩니다. Array.prototype.splice () 문서
ᴍᴀᴛᴛ ʙᴀᴋᴇʀ

9

허용 대답에 건물이 함께 작동합니다 ngRepeat, filter핸들 expections 더 :

제어 장치:

vm.remove = function(item, array) {
  var index = array.indexOf(item);
  if(index>=0)
    array.splice(index, 1);
}

전망:

ng-click="vm.remove(item,$scope.bdays)"

컨트롤러에서 $ scope.vm에 "제거"를 할당하지 않았으므로이 코드는 작동하지 않습니다. 이제 이렇게하면 ... $ scope.vm = {remove : function () {...}}, 그러면됩니다.
Justin Russo

4

컨트롤러없이 구현.

<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<body>

<script>
  var app = angular.module("myShoppingList", []); 
</script>

<div ng-app="myShoppingList"  ng-init="products = ['Milk','Bread','Cheese']">
  <ul>
    <li ng-repeat="x in products track by $index">{{x}}
      <span ng-click="products.splice($index,1)">×</span>
    </li>
  </ul>
  <input ng-model="addItem">
  <button ng-click="products.push(addItem)">Add</button>
</div>

<p>Click the little x to remove an item from the shopping list.</p>

</body>
</html>

splice () 메서드는 배열에 항목을 추가하거나 제거합니다.

array.splice(index, howmanyitem(s), item_1, ....., item_n)

index : 필수입니다. 항목을 추가 / 제거 할 위치를 지정하는 정수입니다. 음수 값을 사용하여 배열 끝에서 위치를 지정하십시오.

howmanyitem (s) : 선택 사항. 제거 할 항목 수입니다. 0으로 설정하면 항목이 제거되지 않습니다.

item_1, ..., item_n : 선택 사항. 배열에 추가 할 새 항목


1
이것이 정답입니다. 간단한 JavaScript 호출을 수행하기 위해 컨트롤러에 의존하는 이유는 무엇입니까?
Elle Fie

3

컨트롤러에서 메소드를 호출해야한다는 것에 동의하지 않습니다. 실제 기능에는 서비스를 사용해야하며, 확장 성 및 모듈화를위한 기능에 대한 지시문을 정의하고 지시문에 삽입 한 서비스에 대한 호출을 포함하는 클릭 이벤트를 지정해야합니다.

예를 들어 HTML에서 ...

<a class="btn" ng-remove-birthday="$index">Delete</a>

그런 다음 지시문을 작성하십시오 ...

angular.module('myApp').directive('ngRemoveBirthday', ['myService', function(myService){
    return function(scope, element, attrs){
        angular.element(element.bind('click', function(){
            myService.removeBirthday(scope.$eval(attrs.ngRemoveBirthday), scope);  
        };       
    };
}])

그런 다음 서비스에서 ...

angular.module('myApp').factory('myService', [function(){
    return {
        removeBirthday: function(birthdayIndex, scope){
            scope.bdays.splice(birthdayIndex);
            scope.$apply();
        }
    };
}]);

이와 같이 코드를 올바르게 작성하면 코드를 재구성하지 않고도 향후 변경 사항을 매우 쉽게 작성할 수 있습니다. 올바르게 구성되어 있으며 사용자 지정 지시문을 사용하여 바인딩하여 사용자 지정 클릭 이벤트를 올바르게 처리하고 있습니다.

예를 들어, 클라이언트가 "이봐, 이제 서버를 호출하고 빵을 만든 다음 모달을 팝업으로 만들자"고 말합니다. HTML 및 / 또는 컨트롤러 메소드 코드를 추가하거나 변경하지 않고도 서비스 자체로 쉽게 이동할 수 있습니다. 컨트롤러에 단 하나의 회선 만 있다면 결국에는 서비스를 사용해야합니다. 기능을 클라이언트가 요청하는 무거운 짐으로 확장 할 수 있습니다.

또한 다른 곳에서 다른 '삭제'버튼이 필요한 경우 이제 지시문 속성 ( 'ng-remove-birthday')이 있으므로 페이지의 모든 요소에 쉽게 할당 할 수 있습니다. 이제 모듈 식으로 재사용 할 수 있습니다. 이것은 Angular 2.0의 HEAVY 웹 컴포넌트 패러다임을 다룰 때 유용합니다. 2.0에는 컨트롤러가 없습니다. :)

행복한 개발 !!!



0

항목에 ID 또는 특정 필드가 있으면 filter ()를 사용할 수 있습니다. Where ()와 같은 동작입니다.

<a class="btn" ng-click="remove(item)">Delete</a>

컨트롤러에서 :

$scope.remove = function(item) { 
  $scope.bdays = $scope.bdays.filter(function (element) {
                    return element.ID!=item.ID
                });
}

0
Pass the id that you want to remove from the array to the given function 

컨트롤러에서 (함수는 동일한 컨트롤러에있을 수 있지만 서비스를 유지하는 것을 선호합니다)

    function removeInfo(id) {
    let item = bdays.filter(function(item) {
      return bdays.id=== id;
    })[0];
    let index = bdays.indexOf(item);
    data.device.splice(indexOfTabDetails, 1);
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.