4

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> 
5
  • When you say mat-list-item does not accept item what do you mean exactly? Commented Dec 2, 2018 at 23:51
  • @fuzz mat-list-item is 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. Commented Dec 2, 2018 at 23:53
  • 1
    how exactly is the Styling off Commented Dec 3, 2018 at 0:03
  • 1
    @NikolaiKiefer Let's just say the structure needs to be exact where mat-list-item has to be directly under mat-list. The styling being incorrect is just a side-effect caused by the incorrect structure. Commented Dec 3, 2018 at 0:04
  • could you provide a screenshot of the styling Commented Dec 3, 2018 at 0:22

1 Answer 1

3

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> 

You're example is looking promising

however have you tried

<mat-list> <mat-list-item *ngFor="let item of items" > <todo-list-item [item]></todo-list-item> </mat-list-item> </mat-list> 

todo-list-item.component.*

 <p>{{ item.title }} - {{ item.description }}</p> 

that way it should be quaranted a mat list item under mat list

Sign up to request clarification or add additional context in comments.

3 Comments

are you sure because the ngfor is different in your example
Sorry about that. Upon reading it again I have noticed that you have moved *ngFor up and onto mat-list. This will create a separate mat-list for each items which is not correct as well.
i tried some options,let me know if the edit is working for you. Or do you get problems with the logic then

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.