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-start및 ng-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-start와ng-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-start과ng-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-start과 ng-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-start과 ng-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.