Angular Lists

Template-ல் items-ன் collections-ஐ display செய்ய கற்றுக்கொள்ளுங்கள்

Angular Lists

Lists template-ல் items-ன் collections-ஐ display செய்கின்றன.

List Rendering Essentials

  • Loop: Stable identity-க்கு track உடன் @if பயன்படுத்தவும் மற்றும் empty states-க்கு @empty பயன்படுத்தவும்.
  • Signals: List state-ஐ signal-ல் store செய்யவும் (e.g., items = signal([...])) மற்றும் immutably update செய்யவும் set()/update() உடன்.
  • Identity: Unnecessary DOM work avoid செய்ய stable key மூலம் track செய்யவும் (e.g., it.id).
  • Derived views: UI-க்கு உங்கள் data-ன் copies-ஐ filter/sort செய்யவும்; source list intact-காக வைக்கவும் (derived state-க்கு computed() பயன்படுத்தவும்).

Basic List Syntax

<ul>
  @for (item of items(); let i = $index; track item) {
    <li>{{ i + 1 }}. {{ item }}</li>
  } @empty {
    <li>No items</li>
  }
</ul>

Note

Control Flow for @for, Conditional Rendering, and Templates for interpolation and basics ஆகியவற்றை காணவும்.

Basic Lists

Loop செய்ய @if பயன்படுத்தவும்; let i = $index உடன் index-ஐ expose செய்யவும்.

Signals உடன் immutably update செய்யவும் (e.g., items.update(arr => [...arr, newItem])).

Basic List Example

<ul>
  @for (item of items(); let i = $index; track item) {
    <li>{{ i + 1 }}. {{ item }}</li>
  } @empty {
    <li>No items</li>
  }
</ul>

Example

@if உடன் basic list render செய்யவும் மற்றும் index-ஐ expose செய்யவும்:

Basic Lists Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal } from '@angular/core';

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Lists</h3>
    <ul>
      @for (item of items(); let i = $index; track item) {
        <li>{{ i + 1 }}. {{ item }}</li>
      } @empty {
        <li>No items</li>
      }
    </ul>
    <button (click)="add()">Add Item</button>
    <button (click)="clear()">Clear</button>
    <button (click)="reset()">Reset</button>
  `
})
export class App {
  items = signal(['Angular', 'React', 'Vue']);
  add() { this.items.update(arr => [...arr, 'Svelte']); }
  clear() { this.items.set([]); }
  reset() { this.items.set(['Angular', 'React', 'Vue']); }
}

bootstrapApplication(App);

Example Explained

  • @for (item of items(); let i = $index; track item): items signal-ல் loops செய்கிறது; zero-based index-ஐ i ஆக expose செய்கிறது; primitive item-ஐ identity-காக பயன்படுத்துகிறது.
  • Buttons: add() immutably append செய்கிறது, clear() empty list-ஐ set செய்கிறது, reset() defaults-ஐ restore செய்கிறது.
  • @empty: Items இல்லாத போது fallback list item-ஐ render செய்கிறது.

Notes

  • No import needed: @if Angular-ன் template syntax-ல் built-in ஆகும்; module import தேவையில்லை.
  • Don't mutate in place: Signals உடன், updates trigger செய்ய new array assign செய்ய set()/update()-ஐ விரும்பவும்.

Lists with track (@for)

List changes-ல், Angular DOM rows-ஐ data items உடன் reconcile செய்கிறது.

track stable identity வழங்குகிறது (e.g., an id) DOM churn minimize செய்ய மற்றும் focus/inputs preserve செய்ய.

Legacy equivalence: *ngFor உடன், அதே effect achieve செய்ய trackBy பயன்படுத்தவும்.

Track Example Syntax

@for (it of items(); track it.id) { <li>{{ it.name }}</li> } @empty { <li>No items</li> }

Example

Track பயன்படுத்தி stable identity உடன் lists render செய்யவும்:

Lists with track Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal } from '@angular/core';

type Item = { id: number; name: string };

@Component({
  selector: 'app-root',
  standalone: true,
  template: `
    <h3>Lists with track</h3>
    <ul>
      @for (it of items(); let i = $index; track it.id) {
        <li>{{ i + 1 }}. {{ it.name }} (id: {{ it.id }})</li>
      }
    </ul>
    <button (click)="renameFirst()">Rename first</button>
    <button (click)="shuffle()">Shuffle</button>
    <button (click)="add()">Add item</button>
  `
})
export class App {
  items = signal([
    { id: 1, name: 'Angular' },
    { id: 2, name: 'React' },
    { id: 3, name: 'Vue' }
  ]);
  nextId = 4;

  renameFirst() {
    this.items.update(arr => arr.map((it, i) => i === 0 ? { ...it, name: it.name + ' *' } : it));
  }

  shuffle() {
    this.items.update(arr => {
      const copy = [...arr];
      for (let i = copy.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [copy[i], copy[j]] = [copy[j], copy[i]];
      }
      return copy;
    });
  }

  add() {
    this.items.update(arr => [...arr, { id: this.nextId++, name: 'New ' + Date.now() }]);
  }
}

bootstrapApplication(App);

Example Explained

  • track it.id: Stable identity வழங்குகிறது அதனால் items shuffle அல்லது update ஆகும் போது Angular DOM rows reuse செய்கிறது, focus மற்றும் local state preserve செய்கிறது.
  • renameFirst(): First item-ன் name-ஐ immutably update செய்கிறது (new object reference) change detection trigger செய்ய.
  • shuffle(): Track உடன் DOM reuse demonstrate செய்ய order-ஐ randomize செய்கிறது.
  • add(): Unique id உடன் new item-ஐ append செய்கிறது.

Notes

  • Avoid index identity: Order மாறக்கூடியால் array index-ஐ identity-காக பயன்படுத்தாதீர்கள்; stable id பயன்படுத்தவும்.
  • Ensure uniqueness: Duplicate id values DOM/UI desync cause செய்யும். Unique keys பயன்படுத்தவும்.
  • *ngFor equivalence: *ngFor உடன், அதே behavior achieve செய்ய trackBy பயன்படுத்தவும்.

Filter & Sort

Signals-அடிப்படையில் computed() உடன் derived view compute செய்யவும்.

உங்கள் data-ன் copies-ஐ filter மற்றும் sort செய்யவும்; easy resets-க்கு source list intact-காக வைக்கவும்.

Filter & Sort Example

import { signal, computed } from '@angular/core';

items = signal([{ name: 'Angular', price: 0 }, { name: 'React', price: 0 }]);
query = signal('');
sortKey = signal<'name' | 'price'>('name');
sortDir = signal<1 | -1>(1);

view = computed(() => {
  const q = query().toLowerCase();
  const dir = sortDir();
  const key = sortKey();
  return items()
    .filter(it => it.name.toLowerCase().includes(q))
    .sort((a, b) => {
      const av: any = (a as any)[key];
      const bv: any = (b as any)[key];
      return av < bv ? -1 * dir : av > bv ? 1 * dir : 0;
    });
});

@for (p of view(); track p.name) {
  <tr>
    <td>{{ p.name }}</td>
    <td>{{ p.price | currency:'USD' }}</td>
  </tr>
}

Example

computed() பயன்படுத்தி lists filter மற்றும் sort செய்யவும்:

Filter & Sort Example

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal, computed } from '@angular/core';
import { CommonModule } from '@angular/common';

type Product = { name: string; price: number };

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule],
  template: `
    <h3>Filter & Sort</h3>
    <div style="display:flex;gap:8px;margin-bottom:8px;">
      <label>Search: <input #q (input)="query.set(q.value)" placeholder="Type to filter..." /></label>
      <button (click)="setSort('name')">Sort by Name</button>
      <button (click)="setSort('price')">Sort by Price</button>
      <button (click)="toggleDir()">{{ sortDir() === 1 ? 'Asc' : 'Desc' }}</button>
    </div>

    <table style="width:100%;border-collapse:collapse;">
      <thead>
        <tr><th style="border:1px solid #ddd;padding:8px;background:#f7f7f7;">Name</th><th style="border:1px solid #ddd;padding:8px;background:#f7f7f7;width:140px;">Price</th></tr>
      </thead>
      <tbody>
        @for (p of view(); track p.name) {
          <tr>
            <td style="border:1px solid #ddd;padding:8px;">{{ p.name }}</td>
            <td style="border:1px solid #ddd;padding:8px;">{{ p.price | currency:'USD' }}</td>
          </tr>
        }
      </tbody>
    </table>
  `
})
export class App {
  items = signal<Product[]>([
    { name: 'Angular', price: 0 },
    { name: 'React', price: 0 },
    { name: 'Vue', price: 0 },
    { name: 'Svelte', price: 0 },
    { name: 'Solid', price: 0 },
    { name: 'Lit', price: 0 }
  ]);
  query = signal('');
  sortKey = signal<'name' | 'price'>('name');
  sortDir = signal<1 | -1>(1); // 1 asc, -1 desc

  view = computed(() => {
    const q = this.query().toLowerCase();
    const dir = this.sortDir();
    const key = this.sortKey();
    return this.items()
      .filter(it => it.name.toLowerCase().includes(q))
      .sort((a, b) => {
        const av: any = (a as any)[key];
        const bv: any = (b as any)[key];
        return av < bv ? -1 * dir : av > bv ? 1 * dir : 0;
      });
  });

  setSort(key: 'name' | 'price') {
    if (this.sortKey() === key) {
      this.toggleDir();
    } else {
      this.sortKey.set(key);
    }
  }

  toggleDir() {
    this.sortDir.set(this.sortDir() === 1 ? -1 : 1);
  }
}

bootstrapApplication(App);

Example Explained

  • computed() view: Signals-லிருந்து source list mutate செய்யாமல் filtered/sorted array derive செய்கிறது.
  • query/sortKey/sortDir: UI-லிருந்து இந்த signals update செய்வதன் மூலம் derived view-ஐ control செய்கிறது.
  • @for (p of view(); track p.name): Derived rows-ஐ render செய்கிறது; identity-க்கு stable key (p.name) பயன்படுத்துகிறது.

Note

Templates-ல் heavy work avoid செய்யவும்; computed() உடன் pre-compute செய்யவும் மற்றும் templates fast-காக வைக்க @if உடன் loop செய்யவும்.

Exercise

Which control flow syntax renders a list from an array?

@for
✓ Correct! @if syntax array-லிருந்து list render செய்கிறது
@more
✗ Incorrect! @more என்பது valid Angular control flow syntax அல்ல
[hidden]
✗ Incorrect! [hidden] element-ஐ CSS மூலம் மறைக்கிறது, list render செய்ய பயன்படாது
அடுத்தது