Issue
I am trying to create a component with multi-slot transclusion in Angular 6, following this blog post (which is for Angular 2).
I created a component:
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'app-criteria',
  template: `
    <div class="adoption-grid-column adopter">
      <div class="adoption-grid-icon ">
        <ng-content select="level-icon"></ng-content>
      </div>
      <div class="adoption-grid-body">
        <ng-content select="level-description"></ng-content>
      </div>
    </div>
  `,
  styles: []
})
export class CriteriaComponent implements OnInit {
  constructor() {}
  ngOnInit() {}
}
and then I am trying to use it like this
<app-criteria>
    <level-icon>
        foo
    </level-icon>
    <level-description>
        bar
    </level-description>
</app-criteria>
But it throws a compile error:
ERROR in : 'level-icon' is not a known element
What am I missing here?
I realize I could create sub-components here, but I'm looking for a solution where I can pass blocks of html into slots in my component (such as bulleted lists, images, etc.)
Solution
The easiest solution (the one I prefer) is to create subcomponents with ng-content as you mentioned. If you don't want to create such components, there are two things you can do.
- CUSTOM_ELEMENTS_SCHEMA
You can tell angular to skip over the components it does not recognize by adding CUSTOM_ELEMENTS_SCHEMA to schema array of your feature module.
E.g.
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
    imports: [...]
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class CustomModule { }
With this way, angular will not complain about level-icon or level-description and transclusion will work just fine. However, setting this option may hide other problems you could have. For example, you can make a typo when using a component and since you told angular you would have CUSTOM_ELEMENTS, it will not give you an error. You end up debugging your code and wondering why the brand new component you just developed is not working. 
- Selecting classes or attributes other than elements.
When you write <ng-content select="level-icon"></ng-content> angular will actually look for html elements called level-icon. You can have it search for classes, attributes etc. So what you can do is to change this 
<ng-content select="level-icon"></ng-content> 
to
<ng-content select="[level-icon]"></ng-content> 
or
<ng-content select=".level-icon"></ng-content> 
And use your component as follows
<app-criteria>
    <div level-icon>
        foo
    </div>
</app-criteria>
or
<app-criteria>
    <div class="level-icon">
        foo
    </div>
</app-criteria>
With this way, you can select for ul, or img. Basically anything you want.
If you still want to use <level-icon> as element, you either have to create a subcomponent or use CUSTOM_ELEMENTS_SCHEMA.
Answered By - Bunyamin Coskuner
 
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.