html 요소가없는 AngularJS ng-repeat


91

현재이 코드를 사용하여 목록을 렌더링하고 있습니다.

<ul ng-cloak>
    <div ng-repeat="n in list">
        <li><a href="{{ n[1] }}">{{ n[0] }}</a></li>
        <li class="divider"></i>
    </div>
    <li>Additional item</li> 
</ul>

그러나이 <div>요소는 일부 브라우저에서 매우 사소한 렌더링 결함을 유발합니다. div 컨테이너없이 ng-repeat를 수행하는 방법이나 동일한 효과를 얻을 수있는 대체 방법이 있는지 알고 싶습니다.


어떤 렌더링 문제에 대해 이야기하고 있습니까?
Ja͢ck

마지막 li 디바이더는 스택 (chrome win7)처럼 약간 두껍게 보입니다. 이것은 CSS 문제가 될 수 있지만 각도로 수정할 수 있는지 알고 싶습니다. 비교를 위해 knockoutJS는 <!-->를 사용하여 컨테이너없는 바인딩을 허용합니다.
nehz

나는 서버 측에서 phptal을 사용하고 그들은 특별히이 목적을 위해 tal : block 태그를 가지고 있습니다. :) DOM이 항상 각도로 더 어려운 새로운 종류의 태그를 받아들이지는 않는 것으로 추측
Ja͢ck

htmlAppend지시어를 사용하는 방법을 반영하도록 html을 업데이트 할 수도 있습니까?
Nick

이것을는 얼마 전에 ... 한 완료,하지만 난 일을 기억하고
nehz

답변:


104

Andy Joslin이 말했듯이 댓글 기반 ng-repeats 작업을하고 있지만 브라우저 문제가 너무 많았습니다 . 다행스럽게도 AngularJS 1.2는 새로운 지시문 ng-repeat-startng-repeat-end.

다음은 Bootstrap 페이지 매김 을 추가하는 간단한 예입니다 .

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>
  <li ng-repeat-start="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
  <li ng-repeat-end class="divider"></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

전체 작동 예제는 여기 에서 찾을 수 있습니다 .

John Lindquist는 또한 그의 훌륭한 egghead.io 페이지에서 이에 대한 비디오 튜토리얼을 가지고 있습니다.


3
요소 인쇄가 필요하지 않습니까?
hitautodestruct

2
<li ng-repeat = "page in [1,2,3,4,5,6]"> <a href="#"> {{page}} </ a > </ li> -edit : 신경
쓰지 마세요.

6
나는 당신이 단지 시연하려고 노력하고 ng-repeat-start/end있지만 이것은 혼란스러운 예이며 잘못된 사용 사례입니다. ng-repeat코드 li가 각 항목에 대해 추가로 빈 공간 을 렌더링하므로 여기서 표준을 사용해야합니다 . 게시물에서 언급해야 할 것입니다.
GFoley83

2
@ GFoley83 맞습니다. 그러나 그는 각 반복마다 추가 요소를 원하는 것으로 보입니다 ng-repeat-start. divider더 명확하게 대답하기 위해 html 클래스를 추가하겠습니다 .
jmagnusson

1
ng-repeat-start그리고 ng-repeat-end혼란 조금 있습니다. 각 문서는 데 도움이 : https://docs.angularjs.org/api/ng/directive/ngRepeat#special-repeat-start-and-end-points
perilandmishap

30

KnockoutJS 컨테이너없는 바인딩 구문

잠시만 기다려주십시오. KnockoutJS는 바인딩 문서 foreach의 Note 4에 설명 된 바인딩에 컨테이너없는 바인딩 구문을 사용하는 매우 편리한 옵션을 제공합니다 foreach. http://knockoutjs.com/documentation/foreach-binding.html

Knockout 문서 예제에서 알 수 있듯이 다음과 같이 KnockoutJS에서 바인딩을 작성할 수 있습니다.

<ul>
    <li class="header">Header item</li>
    <!-- ko foreach: myItems -->
        <li>Item <span data-bind="text: $data"></span></li>
    <!-- /ko -->
</ul>

AngularJS는 이러한 유형의 구문을 제공하지 않는 것이 오히려 불행하다고 생각합니다.


Angular ng-repeat-startng-repeat-end

ng-repeat문제 를 해결하는 AngularJS 방식에서 내가 접한 샘플은 그의 (유용한) 답변에 게시 된 jmagnusson 유형입니다.

<li ng-repeat-start="page in [1,2,3,4,5]"><a href="#">{{page}}</a></li>
<li ng-repeat-end></li>

이 구문을 본 나의 원래 생각은 : 정말? Angular가 내가 아무 관련이없는 추가 마크 업을 강제하는 이유는 무엇이며 Knockout에서 훨씬 더 쉽습니다. 그러나 jmagnusson의 답변에서 hitautodestruct의 의견이 궁금해지기 시작했습니다. 별도의 태그에서 ng-repeat-start 및 ng-repeat-end로 생성되는 것은 무엇입니까?


사용하는 더 깨끗한 방법 ng-repeat-startng-repeat-end

hitautodestruct의 주장을 조사한 결과 ng-repeat-end, 별도의 태그에 추가 하는 것은 완전히 쓸모없는 요소를 생성하기 때문에 대부분의 경우에 수행하고 싶지 않은<li> 것입니다. 이 경우 에는 아무것도없는 항목입니다. Bootstrap 3의 페이지가 매겨진 목록은 불필요한 항목을 생성하지 않은 것처럼 보이도록 목록 항목의 스타일을 지정하지만 생성 된 html을 검사하면 해당 항목이 있습니다.

다행히 : 당신은 청소기 솔루션 및 HTML의 짧은 양을 가지고 많은 작업을 수행 할 필요가 없습니다 그냥 넣어 ng-repeat-end이 같은 HTML 태그에 선언ng-repeat-start .

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>    
  <li ng-repeat-start="page in [1,2,3,4,5]" ng-repeat-end><a href="#"></a></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

이는 3 가지 이점을 제공합니다.

  1. 작성할 HTML 태그 감소
  2. 쓸모없고 빈 태그는 Angular에 의해 생성되지 않습니다.
  3. 반복 할 배열이 비어 있으면 태그가 ng-repeat생성되지 않으므로 Knockout의 컨테이너없는 바인딩이 이와 관련하여 제공하는 것과 동일한 이점을 제공합니다.

그러나 여전히 깨끗한 방법이 있습니다.

더는 각도,이 문제에 대한 GitHub의에서 의견을 검토 한 후 https://github.com/angular/angular.js/issues/1891 ,
당신은 사용할 필요가 없습니다 ng-repeat-startng-repeat-end같은 이점을 얻을 수 있습니다. 대신 jmagnusson의 예를 다시 포크하면 다음과 같이 할 수 있습니다.

<ul class="pagination">
  <li>
    <a href="#">&laquo;</a>
  </li>
  <li ng-repeat="page in [1,2,3,4,5,6]"><a href="#">{{page}}</a></li>
  <li>
    <a href="#">&raquo;</a>
  </li>
</ul>

그래서 때 사용 ng-repeat-start하고 ng-repeat-end? 당으로 각 문서

... 하나의 부모 요소 대신 일련의 요소를 반복합니다 ...

충분히 이야기하고 몇 가지 예를 보여주세요!

그럴 수 있지; 이 jsbin ng-repeat-end은 동일한 태그에서 사용할 때와 사용하지 않을 때 발생하는 일에 대한 다섯 가지 예를 안내합니다 .

http://jsbin.com/eXaPibI/1/


11
질문의 요점을 오해 한 것 같습니다. 목표는 두 개 이상의 목록 항목을 동시에 반복하는 것이며,이를 수행하는 방법을 제공하기 위해 링크 한 예제도 페이지도 아닙니다. 당신이 부착 자신을 언급했듯이 ng-repeat-startng-repeat-end같은 요소에 당신이 각도의 기본값을 사용 할 수있을 때 완전히 쓸모 ng-repeat과 함께 할 수.
Asad Saeeduddin 2014

@Asad- "질문의 요점"은 OP에 의해 명확하게 언급되지 않았습니다. 또한 허용 된 답변의 렌더링 된 DOM 출력을 검사 했습니까? 적어도 확실히 부트 스트랩 페이지 매김 목록이 아닌 그런 종류의 출력을 원하는 사람은 상상할 수 없습니다.
mg1075 2014

1
@ mg1075 예, 허용되는 답변의 출력은 허용되지 않으므로 여기까지 스크롤했습니다. 질문의 요점은 매우 분명합니다. HTML 에서 아티팩트 를 제거하는 ng-repeatOP의 사용에 대한 대안을 적용 하거나 찾는 방법을 찾으십시오 . 질문 의 두 요소에 대해 사용할 방법이 없기 때문에 귀하의 대답은 이것을 수행하지 않습니다 . 내가 틀렸다면 OP 코드를 수정하여 요소 를 제거하는 샘플 마크 업을 제공하십시오 . ng-repeatdivlidiv
Asad Saeeduddin 2014

@Asad-OP가 그가 의도 한 출력의 완성 된 예를 제공했다면 질문의 요점은 더 명확했을 것입니다. 그가 받아 들인 대답이 본질적으로 부적절한 마크 업을 가진 부트 스트랩 페이지 매김을 사용하는 "수락 된"대답을 받아 들였다는 사실은 문제를 더욱 혼란스럽게했습니다. jsbin의 예제 2는 이것이 실제로 의도 된 경우 수락 된 답변이 수행하는 방식으로 OP의 문제를 해결하지만 부트 스트랩 페이지 매김에 해당 유형의 마크 업을 사용해서는 안됩니다. jsbin.com/eXaPibI/1
mg1075

1
사실, 나는 방금 첫 번째 답변을 다시 보았고 생성 된 마크 업은 내 요구 사항을 충족시키지 못하더라도 OP의 사용 사례에 정확히 맞습니다. OP는 jsbin에서 볼 수 li있는 추가 항목 인 구분선 항목이 생성 li되기를 원합니다.
Asad Saeeduddin 2014

6

ngRepeat는 충분하지 않을 수 있지만이를 사용자 지정 지시문과 결합 할 수 있습니다. jQuery를 조금이라도 신경 쓰지 않는다면 코드에 구분선 항목을 추가하는 작업을 위임 할 수 있습니다.

 <li ng-repeat="item in coll" so-add-divide="your exp here"></li>

이러한 간단한 지시문은 실제로 속성 값이 필요하지 않지만 인덱스, 길이 등에 따라 조건부로 구분선을 추가하거나 완전히 다른 것을 추가하는 것과 같은 많은 가능성을 제공 할 수 있습니다.


2
멋진 사용자 지정 지시문을 추가했고 작동합니다. 이 동영상 가이드는 도움 : youtube.com/watch?v=A6wq16Ow5Ec
nehz

3

최근에 임의의 범위와 이미지 컬렉션을 반복해야한다는 동일한 문제가있었습니다.-주변에 요소가있는 것은 옵션이 아닙니다. 그러나 간단한 해결책이 있지만 "null"지시문을 만듭니다.

app.directive("diNull", function() {
        return {
            restrict: "E",
            replace: true,
            template: ""
        };
    });

그런 다음 해당 요소에서 반복을 사용할 수 있습니다. 여기서 element.url은 해당 요소의 템플릿을 가리 킵니다.

<di-null ng-repeat="element in elements" ng-include="element.url" ></di-null>

주변에 컨테이너가없는 여러 템플릿이 반복됩니다.

참고 : 흠 나는 이것이 렌더링 할 때 di-null 요소를 제거한다고 맹세 할 수 있었지만 다시 확인하면 ... 아직도 내 레이아웃 문제를 해결하지 못했습니다 ... 호기심과 호기심 ...


replace2.0부터 사용되지 않습니다.
demalexx 2014

위의 작업을 시도했지만 템플릿 : ""는 아무것도 변경되지 않도록합니다. jsfiddle.net/markcoleman/fMP9s/1 의 링커를 사용 하고 수정했습니다. link : function (scope, element, attrs) {element [0] .outerHTML = ''; $ compile (element.contents ()) (범위); }
라 우리 Lubi

1

주석 지시문 제한이 있지만 ngRepeat는이를 지원하지 않습니다 (반복 할 요소가 필요하기 때문에).

앵귤러 팀이 댓글 ng-repeats에 대해 작업하겠다고 말하는 것을 본 것 같지만 확실하지 않습니다. repo에서 이슈를 열어야합니다. http://github.com/angular/angular.js


2012 년의 코멘트. 이것이 여전히 사실입니까? 문서에서 검색을 시도했지만 참조를 찾을 수 없습니다.
Zack S

1

이 작업을 수행하는 Angular 마법의 방법은 없습니다. Bootstrap을 사용하는 경우 유효한 HTML을 얻기 위해이 작업을 수행 할 수 있습니다. 그러면 li.divider를 추가하는 것과 동일한 효과를 얻을 수 있습니다.

수업 만들기 :

span.divider {
 display: block;
}

이제 코드를 다음과 같이 변경하십시오.

<ul ng-cloak>
 <li div ng-repeat="n in list">
    <a href="{{ n[1] }}">{{ n[0] }}</a>
    <span class="divider"></span>
 </li>
 <li>Additional item</li>
</ul>

1

실제로 작동하는 솔루션

HTML

<remove  ng-repeat-start="itemGroup in Groups" ></remove>
   html stuff in here including inner repeating loops if you want
<remove  ng-repeat-end></remove>

angular.js 지시문 추가

//remove directive
(function(){
    var remove = function(){

        return {    
            restrict: "E",
            replace: true,
            link: function(scope, element, attrs, controller){
                element.replaceWith('<!--removed element-->');
            }
        };

    };
    var module = angular.module("app" );
    module.directive('remove', [remove]);
}());

간단한 설명을 위해

ng-repeat는 자신을 <remove> 요소와 루프에 ng-repeat-start / ng-repeat-end를 사용했기 때문에 요소뿐만 아니라 html 블록을 루프합니다.

그런 다음 사용자 정의 제거 지시문은 <remove>시작 및 종료 요소를<!--removed element-->


이건 재미 있네. 그러나 내 테스트 replaceWith(...)결과 주석이 아닌 텍스트 노드가 생성됩니다. 나는 단지 element.remove()작품을 사용하는 것을 발견했습니다 .
artfulrobot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.