AngularJS element directives not displaying when using self-closing tags
Asked Answered
A

4

22

I have in my html file directives

<add />
<back />

and the directives are on the form

.directive('add', ['$window', ...

and

.directive('back', ['$window', 

This works fine.

If i change the directives to camel case:

.directive('addPlayer', ['$window', ...

<add_player />
<back />

and

<add:player />
<back />

display fine whereas

<add-player />  regular dash
<back />

displays only <add-player> and everything after is not displayed.

Any ideas why?

EDIT:

I've kind of gotten the same behaviour here

http://plnkr.co/edit/cpP4c2TyZwv5Y4BrNUBb?p=preview

Aeriel answered 7/8, 2013 at 12:18 Comment(1)
Angular2: Still no. See issue #5563.Unbolt
T
44

To lay your question to rest, I am quoting the official statement from the AngularJS team: (sic)

self-closing or void elements as the html spec defines them are very special to the browser parser. you can't make your own, so for your custom elements you have to stick to non-void elements (<foo></foo>).

this can't be changed in angular.

- IgorMinar

source: https://github.com/angular/angular.js/issues/1953#issuecomment-13135021

Follow the rest of the conversation on AngularJS issue's page where they discuss the possibility of using XHTML for delivering content with self-closing tags that is acceptable to the browser. However do note that it is not fully supported by AngularJS.

Taille answered 29/7, 2014 at 9:47 Comment(3)
Spent 2 hours on this. never thought that self-closing tags would be so annoying and dangerous. Will not be using self-closing tags for a long long time now when working with Angular. Thanks for the answer by the way.Horvath
then why is it allowed in reactJS? react-redux.js.org/introduction/…Abbey
@Abbey - React uses JSX which looks very much like HTML, but in reality is not. The code you have linked to isn't what gets injected directly in the browser. React renders that to JavaScript. See that in action on Babbel REPLTaille
O
11

HTML spec does not allow self-closing tags on non-void elements.

HTML syntax rules [W3C]

Elements have a start tag to indicate where they begin. Non-void elements have an end tag to indicate where they end.
Start tags consist of the following parts, in exactly the following order:

  1. A "<" character.
  2. The element’s tag name.
  3. Optionally, one or more attributes, each of which must be preceded by one or more space characters.
  4. Optionally, one or more space characters.
  5. Optionally, a "/" character, which may be present only if the element is a void element.
  6. A ">" character.

There is a limited number of void elements in HTML5 spec. Here is the complete list:

area, base, br, col, command, embed, hr, img, input, keygen, link, meta, param, source, track, wbr.

What's really going on

The browser's parser has to listen to the spec. Since using the slash in a non-void element tag is invalid, the parser ignores the ending />, and <back /> means <back>. Therefore you are never closing the first element which prevents the others to work.

On Plunker you have:

<body>
   <back></back>
   Self closing <back />
   Self closing <back />
</body>

which parses into

<body>
   <back></back>
   Self closing <back>
      Self closing <back>
    </back>
  </back>
</body>

You then specify template: '<button>back</button>' on your directive which replaces back (and it's children) with the specified HTML resulting in:

<body>
   <back>
       <button>back</button>
   </back>
   Self closing <back>
       <button>back</button>
   </back>
</body>

What should I do then?

Use <back></back> for all and it will work fine. Alternatively you could use element attributes: <div back="attr"></div>.

See the following discussions for more details:

Ossified answered 30/7, 2015 at 12:47 Comment(2)
then why does reactJS allow self closing tags? react-redux.js.org/introduction/…Abbey
@Abbey is ReactJS code HTML or XHTML? I doubt so. https://mcmap.net/q/487699/-react-component-closing-tagOssified
P
6

I've run into the same problem recently and managed to fix it by not using self-closing tags. Try <add-player></add-player> instead of the self-closing version.

I don't know why self-closing tags don't work with dashes in the directive's tag name. Did a quick research back in the day and didn't find anything on the HTML/XHTML side. Perhaps a bug/limitation in Angular?

Plunge answered 7/8, 2013 at 13:54 Comment(1)
yes, it looks like <back/> only starts it so I could put <back/("/" optional)> </back> and it works. The strange thing is that I got some of them to be displayed after each other and some not. But the docs use <back></back>, so I guess the self closing ones are not the way to go.Aeriel
N
0

Angular v15.1.0 now has added support to self-closing tags on custom elements.

Check it out: https://github.com/angular/angular/blob/main/CHANGELOG.md

Needham answered 14/1, 2023 at 23:33 Comment(1)
This looks more like a comment rather than an answer. You could try answering yourself instead of posting a linkSisterinlaw

© 2022 - 2024 — McMap. All rights reserved.