42

Is here an AngularJS equivalent for Angular ng-container?

Or should I create something myself with a transclude directive?


Example use cases:

  1. Tables with interlaced pairs, triples etc. of cells:

    <table><tr>
      <ng-container ng-repeat="item in items">
        <td>{{ item.a }}</td>
        <td>{{ item.b }}</td>
      </ng-container>
    </tr></table>
    

    There should not be additional level in the DOM tree, and instead <td>s should be direct children of <tr> element.

  2. There is similar problem with HTML lists, especially the definiton list where <dt> / <dd> elements should be direct children of <dl> while they usually exist in pairs.

  3. Table-like arrangement of data with display:grid:

    <div style="display: grid; grid-template-columns: auto auto">
        <ng-container ng-repeat="item in items">
            <div>{{ item.a }}</div>
            <div>{{ item.b }}</div>
        </ng-container>
    </div>
    

    This case is even more problematic as the container element existing in DOM tree causes the whole layout to break, as it is rendered as the cell instead of its children.

jaboja
  • 2,178
  • 1
  • 21
  • 35
mvermand
  • 5,829
  • 7
  • 48
  • 74

3 Answers3

25

In cases you have mentioned, you can use ng-repeat-start and ng-repeat-end pair, respectively:

  1. Tables with interlaced pairs, triples etc. of cells:

    <table><tr>
      <td ng-repeat-start="item in items">{{ item.a }}</td>
      <td ng-repeat-end>{{ item.b }}</td>
    </tr></table>
    
  2. HTML lists:

    <dl>
      <dt ng-repeat-start="item in items">{{ item.term }}</dt>
      <dd ng-repeat-end>{{ item.definition }}</dd>
    </dl>
    
  3. Table-like arrangement of data with display:grid:

    <div style="display: grid; grid-template-columns: auto auto">
      <div ng-repeat-start="item in items">{{ item.a }}</div>
      <div>{{ item.b }}</div>
      <div ng-repeat-end>{{ item.c }}</div>
    </div>
    

You can read about this in API reference: https://docs.angularjs.org/api/ng/directive/ngRepeat#special-repeat-start-and-end-points

5

Unfortunately in AngularJS ng-repeat, ng-if, etc must be used on an HTML element that will be present in the markup. Depending on the exact use-case you could try using an element directive with replace: true.

ach
  • 6,164
  • 1
  • 25
  • 28
  • 3
    Could you provide some code example for use case where introduction of additional DOM tree level is forbidden due to HTML semantics, like in case of adding table cells or child nodes to some `display:grid` element? – jaboja Jul 11 '18 at 12:58
1

You can use the same ng-container in both Angularjs and Angular-2 as well. But in angular-2 have an additional option is ng-template which is act as ng-container

Ramesh Rajendran
  • 37,412
  • 45
  • 153
  • 234
  • 12
    I use ng-container in AngularJS 1.6.3 and I see that the ng-container element is included in the DOM of the browser. Also, Webstorm says "Unknown HTML tag ng-container". So it is not working as expected in my project. – mvermand Apr 23 '18 at 08:17
  • @mvermand You need to add the `angular-material.js` file as a Library in WebStorm:Please check https://stackoverflow.com/questions/28701863/how-do-i-teach-webstorm-9-inspector-to-recognize-angular-material-design-tags-at – Ramesh Rajendran Jul 16 '18 at 12:00
  • @RameshRajendran the original question had nothing to do with WebStorm. Could you please elaborate your answer? – Aleksei Egorov Mar 31 '20 at 15:14
  • this is not working for angularJs versions without any libs – messerbill Jan 25 '21 at 15:37