Akhilesh Kumar
Akhilesh Kumar

Reputation: 9355

how to use selector similar to ng-container in angular-4.x

I'm using angular-4.x and inside component I'm using some 'abc' Selector as below:

@Component({
  selector: "Abc",
  templateUrl: "Abc.html",
  styleUrls: [
    "Abc.css"
  ]
})

but "Abc" tag is present in DOM as well but I want it to behave as "ng-container" which only reflect child DOM in page not the tag itself.

Upvotes: 3

Views: 3105

Answers (1)

Lazar Ljubenović
Lazar Ljubenović

Reputation: 19754

This might or might not work for you, depending on the use-case.

Anyway, your selector doesn't have to be a tag selector, it could just as well be an attribute selector, which means that no new tag will be added in the rendered output.

So, if your component has the following metadata...

selector: '[abc]',
template: `<ng-content></ng-content>`
styles: [`:host { background-color: red }`],

And you use it like this...

<div abc>
  <span>Hello <b>world!</b></span>
</div>

The rendered output would be exactly that (no <abc> tag added).


Another possible "solution" is to use ARIA to assign a role to your custom element. For example, if you want <abc> to be a button, you can do something like this in the class.

@HostBinding('role') role = 'button'

This means that, semantically, it's still a button, even though it's not a <button> element.

Again, might or might not work for your use-case but it's an idea for a workaround.


Otherwise, it's impossible to currently a component which does what you want. Structural directives come in close, but then you will not be able to apply styles, because styles is not valid metadata for a @Directive.

But you can create a no-operation structural directive by injecting ViewContainerRef and TemplateRef and just instantiating the template in the OnInit lifecycle hook.

constructor(private templateRef: TempalteRef,
            vcr: ViewContainerRef) {
}

ngOnInit() {
  this.vcr.createEmbeddedView(this.templateRef)
}

But you would still have to use it with <ng-container>, if you don't want a rendered element encapsulating its content. So your request "like <ng-container> but different isn't really cutting it in this case.

Upvotes: 2

Related Questions