Angular 5中实现ngFor每3个<li>后自动闭合并重建<ul>
<ul> Every 3 <li> in Angular 5 Got it, let's work through this! In Angular, you can't directly conditionally open/close DOM tags like <ul> within an *ngFor loop—Angular's template renderer expects valid, nested structure, so that approach would throw syntax errors. Instead, the cleanest fix is to first split your events array into chunks of 3 items, then loop over those chunks to create separate <ul> elements.
Option 1: Component Method (Quick One-Off Fix)
First, add a method to your component class that splits the array into chunks:
// Inside your component class splitEventsIntoChunks(chunkSize: number = 3): any[][] { const eventChunks = []; for (let i = 0; i < this.events.length; i += chunkSize) { eventChunks.push(this.events.slice(i, i + chunkSize)); } return eventChunks; }
Then update your template to loop over the chunks first (each chunk gets its own <ul>), then loop over the events in each chunk to generate <li>s:
<section class="tickets-block"> <div class="container small"> <div class="our-team"> <!-- Loop over chunks to create new <ul> elements --> <ul *ngFor="let chunk of splitEventsIntoChunks()"> <!-- Loop over events in the current chunk to create <li>s --> <li class="custom" *ngFor="let event of chunk; let i=index"> {{event.name}} </li> </ul> </div> </div> </section>
Option 2: Reusable Pipe (Great for App-Wide Use)
If you need this chunking logic in multiple components, create a custom pipe instead:
// chunk.pipe.ts import { Pipe, PipeTransform } from '@angular/core'; @Pipe({ name: 'chunk' }) export class ChunkPipe implements PipeTransform { transform(items: any[], chunkSize: number): any[][] { const chunks = []; for (let i = 0; i < items.length; i += chunkSize) { chunks.push(items.slice(i, i + chunkSize)); } return chunks; } }
Don't forget to register this pipe in your module's declarations array so Angular recognizes it:
// your-module.module.ts import { ChunkPipe } from './chunk.pipe'; @NgModule({ declarations: [ // ... other components/pipes ChunkPipe ] }) export class YourModule { }
Now use the pipe directly in your template:
<section class="tickets-block"> <div class="container small"> <div class="our-team"> <ul *ngFor="let chunk of events | chunk:3"> <li class="custom" *ngFor="let event of chunk; let i=index"> {{event.name}} </li> </ul> </div> </div> </section>
Why This Works
By splitting the array first, you're letting Angular render valid, well-structured DOM—each <ul> holds exactly 3 (or fewer, for the final partial chunk) <li> elements, which matches your requirement. This avoids messy attempts to manually manipulate tag opening/closing, which Angular doesn't support in templates.
内容的提问来源于stack exchange,提问作者NewUser

