Programing

html 요소가없는 AngularJS ng-repeat

lottogame 2020. 9. 5. 10:30
반응형

html 요소가없는 AngularJS ng-repeat


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

<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를 수행하는 방법이나 동일한 효과를 얻을 수있는 대체 방법이 있는지 알고 싶습니다.


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 페이지에서 이에 대한 비디오 튜토리얼을 가지고 있습니다.


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을 검사하면 해당 항목이 있습니다.

Fortunately, you do not need to do much to have a cleaner solution and a shorter amount of html: just put the ng-repeat-end declaration on the same html tag that has the 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>

This gives 3 advantages:

  1. less html tags to write
  2. useless, empty tags are not generated by Angular
  3. when the array to repeat is empty, the tag with ng-repeat won't get generated, giving you the same advantage Knockout's containerless binding gives you in this regard

But there is still a cleaner way

After further reviewing the comments in github on this issue for Angular, https://github.com/angular/angular.js/issues/1891,
you do not need to use ng-repeat-start and ng-repeat-end to achieve the same advantages. Instead, forking again jmagnusson's example, we can just go:

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

So when to use ng-repeat-start and ng-repeat-end? As per the angular documentation, to

...repeat a series of elements instead of just one parent element...

Enough talk, show some examples!

Fair enough; this jsbin walks through five examples of what happens when you do and when you don't use ng-repeat-end on the same tag.

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


ngRepeat may not be enough, however you can combine that with a custom directive. You could delegate the the task of adding divider items to code if you don't mind a little bit of jQuery.

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

Such a simple directive doesn't really need an attribute value but might give you lots of possiblities like conditionally adding a divider according to index, length, etc or something completely different.


I recently had the same problem in that I had to repeat an arbitrary collection of spans and images - having an element around them was not an option - there's a simple solution however, create a "null" directive:

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

You can then use a repeat on that Element, where element.url points to the template for that element:

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

This will repeat any number of different templates with no container around them

Note: hmm I could've sworn blind this removed the di-null element when rendering, but checking it again it doesn't...still solved my layout issues though...curioser and curioser...


There is a comment directive restriction, but ngRepeat doesn't support it (since it needs an element to repeat).

I think I saw the angular team say they would work on comment ng-repeats, but I'm not sure. You should open an issue for it on the repo. http://github.com/angular/angular.js


There is no Angular magic way to do this, for your case you can do this, to get valid HTML, if you are using Bootstrap. Then you will get same effect as adding the li.divider

Create a class:

span.divider {
 display: block;
}

Now change your code to this:

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

for a solution that really works

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>

add an angular.js directive

//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]);
}());

for a brief explanation,

ng-repeat binds itself to the <remove> element and loops as it should, and because we have used ng-repeat-start / ng-repeat-end it loops a block of html not just an element.

then the custom remove directive places the <remove> start and finish elements with <!--removed element-->

참고URL : https://stackoverflow.com/questions/12857714/angularjs-ng-repeat-with-no-html-element

반응형