toggle menu

[AngularJS] ng-repeat 사용방법 정리

2013. 7. 5. 10:43 AngularJS
AngularJS를 활용해서 웹어플리케이션을 개발할 때 가장 많이 사용하게 되는 다이렉티브 중 하나가 ng-repeat 일 것이다.
간단하게 배열 안의 요소들을 알아서 출력해줄 수 있기 때문에 활용도가 높다.

하지만 단순한 사용법만 숙지한 상태에서 ng-repeat을 쓰게 되면, 복잡한 케이스를 만났을 때 많은 한계를 느끼게 된다.
AngularJS 사이트에서 제공하는 ng-repeat 에 대한 설명을 살펴보면, $index, $first 등 다소 특별한 속성들이 있는데 이 특별한 속성들을 사용하면 이러한 한계를 상당부분 해소할 수 있다.


$index – {number} – 현재 반복 요소의 오프셋 (0부터 length-1까지)
$first – {boolean} – 현재 반복 요소가 첫번째 요소이면 true
$middle – {boolean} – 현재 반복 요소가 처음도 끝도 아니면 true
$last – {boolean} – 현재 반복 요소가 마지막 요소이면 true

 

아래와 같은 조건을 가진 레이아웃을 생각해보자. ng-repeat 을 활용해서 구현하려면 어떻게 해야할까?

1. TH 태그를 활용해서 테이블 헤드가 왼편에 보여야 한다.
2. 입력 요소는 5개까지 가능하고 마지막 입력 요소에는 추가 버튼이 보여야 한다.
3. 5개까지 입력요소가 추가되면 추가 버튼은 감춰져야 한다.
4. 입력 요소는 삭제 버튼으로 삭제될 수 있고, 마지막 요소는 삭제되면 안되고 초기화 되어야 한다.
5. 각 입력 요소에서 검색 버튼을 누르면 해당 요소의 내용이 출력되어야 한다.


1번부터 쉽지 않아 보인다.
TH는 하나만 나와야 하는데 TR을 반복시키면 TH가 여러개 생겨버리게 된다. 어떻게 처리해야 할까?
$first 속성을 활용하면 생각보다 간단하게 처리해 줄 수 있다.

<tr data-ng-repeat="row in list">
    <th rowspan="{{list.length}}" data-ng-show="$first">테이블 헤드</th>


th 태그의 rowspan 속성은 list의 길이로 잡아주고, 여러 개의 th가 생성되어도 첫번째 th만 보이도록 data-ng-show 를 활용하면 된다. $first 속성이 없었다면 훨씬 복잡해질 수 있는 부분을 쉽게 처리할 수 있었다.


2번과 3번은 어떻게 처리해야 할까? 요소를 추가할 때 5개까지만 추가되어야 하고 마지막 요소에만 추가 버튼이 보여야한다.
아래와 같이 $last 속성과 $index 속성을 활용하면 쉽게 구현할 수 있다.

<a href="javascript:;" data-ng-click="clickListener('btn_addrow')" data-ng-show="$last && ($index < 4)">행 추가</a>

각 반복 행마다 추가 버튼이 실제로는 존재하겠지만, data-ng-show를 활용해 $last 즉, 마지막인 경우와, $index < 4 인 경우에만 행 추가 버튼이 나타나는 것이다.


4번은 비교적 쉬워보인다. 하지만 $index 를 모른다면 한참은 더 어렵게 처리해야 한다.
먼저 삭제 버튼을 눌렀을 때 해당 요소의 $index 를 파라메터로 보낸다. $index를 통해 실제 배열에서의 위치를 알 수 있게 때문에 splice를 통해 간단하게 삭제해줄 수 있다.

<!-- HTML -->
<a href="javascript:;" data-ng-click="clickListener('btn_deleterow', $index)">삭제</a>


//JavaScript
if( $scope.list.length > 1 ) {
    $scope.list.splice($index, 1);
}
else {
    $scope.list = [{ rowNm: "", rowLabel : "입력"}];
}

 
5번이 가장 쉽다. 현재 요소를 그냥 파라메터로 넘겨버리고 거기에서 값을 출력하게 처리하면 되기 때문이다.




결론

지금까지 살펴본 내용을 jsFiddle 로 만들어보았다. 직접 테스트해보고 수정해보면서 ng-repeat 과 특별한 속성들을 어떻게 활용할 수 있는지에 대한 인사이트를 조금이라도 얻기를 기대해본다.






AngularJS 관련 포스팅 더보기