Suppose I am creating a typical to-do list that has a structure as following:
<ul> <li>Item 1 - description for item 1</li> <li>Item 2 - description for item 2</li> <!-- ... --> </ul> I would like the list and the items to be as reusable as possible, and so I can make them into separate components:
todo-list.component.*
@Component({ selector: "todo-list", templateUrl: "todo-list.component.html" }) export class TodoListComponent { /* ... */ } <ul> <li todo-list-item *ngFor="let item of items" [item]="item"></li> </ul> todo-list-item.component.*
@Component({ selector: "li[todo-list-item]", templateUrl: "todo-list-item.component.html" }) export class TodoListItemComponent { /* ... */ } {{ item.title }} - {{ item.description }} So far everything will work as long as I stick with native HTML elements such as ul and li.
However an issue arises when I try to use Angular components instead native elements such as mat-list and mat-list-item:
todo-list.component.*
<mat-list> <mat-list-item todo-list-item *ngFor="let item of items" [item]="item"></mat-list-item> </mat-list> todo-list-item.component.*
{{ item.title }} - {{ item.description }} The snippets above do not work. mat-list-item does not accept item and also now there are two component definitions that matches mat-list-item[todo-list-item].
I can do it this way:
todo-list.component.*
<mat-list> <todo-list-item *ngFor="let item of items" [item]="item"></todo-list-item> </mat-list> todo-list-item.component.*
<mat-list-item> {{ item.title }} - {{ item.description }} </mat-list-item> However now the structure is not correct and it will not produce the correct styling:
<mat-list> <todo-list-item> <mat-list-item>Item 1 - description for item 1</mat-list-item> </todo-list-item> <todo-list-item> <mat-list-item>Item 2 - description for item 2</mat-list-item> </todo-list-item> </mat-list> mat-list-item should be directly under mat-list:
<mat-list> <mat-list-item>Item 1 - description for item 1</mat-list-item> <mat-list-item>Item 2 - description for item 2</mat-list-item> </mat-list> I am aware that I can combine the two components into a single one, however each of the list items can be fairly complex (with buttons and additional logic) that I would like them to be in separate components. What is the usual approach to this problem? Many of the related questions (such as this and this) that I could find assume native elements are used, which is not the case here. Specifically, how do I create the following structure using two components that I can define myself?
<todo-list> <mat-list> <mat-list-item>Item 1 - description for item 1</mat-list-item> <mat-list-item>Item 2 - description for item 2</mat-list-item> </mat-list> </todo-list>
mat-list-itemdoes not acceptitemwhat do you mean exactly?mat-list-itemis an Angular component that is already defined instead of a native HTML element that I can redefine by using the selector. Because of that, I don't have control over its inputs.mat-list-itemhas to be directly undermat-list. The styling being incorrect is just a side-effect caused by the incorrect structure.