78

I am getting started with the Angular 2 (version 2.0.0-alpha.46) and creating a few components.

When creating the component with the below code:

Typescript:

import {ComponentMetadata as Component, ViewMetadata as View} from 'angular2/angular2';

@Component({
   selector: 'my-component'
})

@View({
     template: '<div class="myClass">Hello My component</div>'
 })

export class MyCompoent{
    constructor() {
        console.info('My Component Mounted Successfully');
    }
}

HTML:

<my-component></my-component>

It works fine, but when i do Inspect element, I can see a tag generated like this:

Output HTML

<my-component>
    <div>Hello My component</div>
<my-component>

Problem

it keeps the <my-component> tag in the HTML, and some of my CSS are not working as expected.

Question

Is there a way to remove the <my-component> tag similar to angular 1 (replace: true in the directive)?

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
powercoder23
  • 1,404
  • 1
  • 13
  • 22
  • 3
    Just FYI, this has been asked at least 3 times already: [1](http://stackoverflow.com/questions/34280475/remove-the-host-html-element-selectors-created-by-angular-component), [2](http://stackoverflow.com/questions/34480243/is-there-way-to-create-component-those-html-template-replaces-custom-selector), [3](http://stackoverflow.com/questions/34556277/angular2-table-rows-as-component). – Mark Rajcok Jan 05 '16 at 03:12
  • 1
    The duplicates simply highlight the various scenarios this feature is required in. As this question points out, the CSS libraries don't work as expected with Angular because of this. – Karma Sep 20 '17 at 18:44

2 Answers2

68

Replace was deprecated in AngularJS 1.x according to https://github.com/angular/angular/issues/3866 because it seemed to not be a good idea.

As a workaround you can use an attribute selector in your component like

selector: '[my-component]'

selector: '[myComponent]'

and then use it like

<div my-component>Hello My component</div>

<div myComponent>Hello My component</div>

hint

Directive selectors should be camelCase instead of snake-case. Snake-case is only used for element selectors, because the - is required for custom elements. Angular doesn't depend on components being custom elements, but it's considered good practice to comply with this rule anyway. Angular works fine with camelCase attributes and uses them with all directives (*ngFor, ngModel, ...), and is also suggested by the Angular style guide.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 8
    camelCase is **not** the preferred style for selectors of components. See [Style 05-02](https://angular.io/docs/ts/latest/guide/style-guide.html#05-02) – freethebees Jun 16 '16 at 13:39
  • 3
    That only applies to **tag names**. For **attribute selectors** there is no reason not to use camelCase. They would prefer camelCase names for tag selectors as well but this wouldn't match the WebComponents naming style where a `-` in the name is **required**. This doesn't cause much harm though because Angular doesn't depend on WebComponents features. The only minor difference is that Tags that don't have a `-` inherit from `HTMLUnknownElement` instead of `HTMLElement` See also http://www.html5rocks.com/en/tutorials/webcomponents/customelements/#upgrades – Günter Zöchbauer Jun 16 '16 at 13:47
  • 2
    It is suggested to avoid this according to Angular 2's style guide 05-03, https://angular.io/docs/ts/latest/guide/style-guide.html#!#05-03 – Logan H Dec 20 '16 at 21:47
  • 2
    Sure, but there are situations where that is mandatory. How would you otherwise be able to make a `` or a `
  • ` a component where no other tag names are supported?
  • – Günter Zöchbauer Dec 20 '16 at 21:55
  • @LoganH But what's the alternative? According to http://w3c.github.io/webcomponents/spec/custom/ it seems to be valid HTML5 when a child-component gets rendered as `` element. For modern browsers thats fine. If you have older ones, especially MS IE, this may cause trouble. – Lion Feb 03 '17 at 17:56
  • 1
    See Gunters comment right under mine, he explains one scenario where you can't avoid this. It is suggested to _avoid_, but if you have to do it, you can – Logan H Feb 03 '17 at 18:03
  • 1
    i wonder if angularjs's replace feature could be simulated with . i havent tried it yet. – Alexander Taylor May 25 '17 at 06:59
  • 1
    It's not possible to set an attribute in a ng-container, i have tried it right now, but unfortunately it's not a solution @AlexanderTaylor – Kangcor May 25 '17 at 08:45
  • Not sure what you mean. `` is never added to the DOM, so adding attributes doesn't make sense – Günter Zöchbauer May 26 '17 at 07:00
  • it's just not enough in some cases: https://stackoverflow.com/questions/45936991/button-group-split-in-2-components – bvdb Aug 29 '17 at 16:21
  • @GünterZöchbauer what about `router-outlet` component loading? – Ben Racicot Dec 06 '17 at 14:43
  • @BenRacicot I don't understand what you mean. `` will add an element with the name of the components selector as sibling of `` – Günter Zöchbauer Dec 06 '17 at 14:45
  • @GünterZöchbauer yes, can you load components without the wrapper selector there as well? With `router-outlet` we don't have the option of using attributes do we? – Ben Racicot Dec 06 '17 at 15:21
  • Can you please explain what you try to accomplish? There is no way to **not** have the wrapper element. What my answer above explains is, that the element tag can be custom. If you use the router-outlet, there is no way to specify a custom element name. – Günter Zöchbauer Dec 06 '17 at 15:23
  • 1
    @GünterZöchbauer I see. I'm trying to "flatten" my markup for more efficient use of CSS grid. It would be perfect for grid layout if we could display component view html without the wrapping element but doesnt look like that's possible... Thanks for replying. – Ben Racicot Dec 06 '17 at 19:53
  • @mik01aj Case sensitive support was only added several months after I posted this answer. Thanks a lot for reviving it :) – Günter Zöchbauer Dec 07 '17 at 14:56