Angular ro‘yxatlari


Ro‘yxatlar shablondagi elementlar to‘plamini ko‘rsatadi.


ULASHISH

Rendering Essentials ro‘yxati

  • Loop: Barqaror identifikatsiya uchun @for bilan track va bo‘sh holatlar uchun @empty foydalaning.
  • Signallar: Ro‘yxat holatini signalda saqlang (masalan, items = signal([...]) ) va set() / update() bilan o‘zgarmas holda yangilang.
  • Identifikatsiya: keraksiz DOM ishining oldini olish uchun barqaror kalit (masalan, it.id) orqali kuzating.
  • Olingan ko‘rinishlar: UI uchun ma’lumotlaringiz nusxalarini filtrlash/saralash; manbalar ro‘yxatini buzilmasdan saqlang (hosil holati uchun computed() dan foydalaning).
Eslatma: Interpolatsiya va asoslar uchun @for uchun boshqaruv oqimi, shartli ko‘rsatish va shablonlarga qarang.

Asosiy massivlar

  • Loop uchun @for dan foydalaning; indeksni let i = $index bilan oching.
  • Signallar bilan o‘zgarmas yangilang (masalan, items.update(arr => [...arr, newItem]) ).
<ul>
  @for (item of items(); let i = $index; track item) {
    <li>{{ i + 1 }}. {{ item }}</li>
  } @empty {
    <li>No items</li>
  }
</ul>

Misol

@for bilan asosiy massivni yarating va indeksni ko‘rsating:

Misol

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);
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • @for (item of items(); let i = $index; track item) : items signali ustidan aylanishlar; nolga asoslangan indeksni i sifatida ko‘rsatadi; identifikator sifatida ibtidoiy item o‘zidan foydalanadi.
  • Tugmalar: add() o‘zgarmas qo‘shiladi, clear() bo‘sh massivni o‘rnatadi, reset() standart sozlamalarni tiklaydi.
  • @empty: Elementlar mavjud bo‘lmaganda zaxira massiv elementini ko‘rsatadi.

Eslatmalar:

  • Import qilish shart emas: @for Angular shablon sintaksisiga kiritilgan; modul importi talab qilinmaydi.
  • Joyda mutatsiyaga uchramang: signallar bilan yangi massivni belgilash va yangilanishlarni ishga tushirish uchun set()/update() ni afzal ko‘ring.


Trekli ro‘yxatlar (@for)

  • Ro‘yxat o‘zgarishlarida Angular DOM qatorlarini ma’lumotlar elementlari bilan moslashtiradi.
  • track barqaror identifikatorni (masalan, id ) ta’minlaydi, bu DOM buzilishini minimallashtirish va fokus/kirishlarni saqlab qolish uchun.
  • Eski ekvivalentlik: *ngFor bilan bir xil effektga erishish uchun trackBy dan foydalaning.
@for (it of items(); track it.id) { <li>{{ it.name }}</li> } @empty { <li>No items</li> }

Misol

Ro‘yxatlarni track yordamida barqaror identifikator bilan chiqaring:

Misol

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);
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • track it.id: Barqaror identifikatsiyani ta’minlaydi, shuning uchun Angular elementlar aralashgan yoki yangilanganda DOM qatorlarini qayta ishlatadi, fokus va mahalliy holatni saqlaydi.
  • renameFirst(): O‘zgarishlarni aniqlashni ishga tushirish uchun birinchi element nomini o‘zgarmas (yangi obyektga havola) yangilaydi.
  • shuffle() : track bilan DOMdan qayta foydalanishni namoyish qilish uchun tartibni tasodifiylashtiradi.
  • add(): Noyob identifikatorga ega yangi elementni qo‘shadi.

Eslatmalar:

  • Indeks identifikatoridan saqlaning: Agar tartib o‘zgarishi mumkin bo‘lsa, massiv indeksini identifikatsiya sifatida ishlatmang; barqaror identifikatordan foydalaning.
  • Yagonalikni ta’minlang: takroriy id qiymatlari DOM/UI sinxronizatsiyasini keltirib chiqaradi. Noyob kalitlardan foydalaning.
  • *ngFor ekvivalentlik: *ngFor bilan bir xil harakatga erishish uchun trackBy dan foydalaning.

Filtrlash va saralash

  • Signallar asosida olingan view ni computed() bilan hisoblang.
  • Ma’lumotlaringiz nusxalarini filtrlang va tartiblang; oson tiklash uchun manbalar ro‘yxatini buzilmasdan saqlang.
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>
}

Misol

computed() yordamida ro‘yxatlarni filtrlang va tartiblang.

Misol

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);
<app-root></app-root>

Misolni ishga tushirish »

Misol tushuntirildi

  • computed() ko‘rinishi: manbalar ro‘yxatini o‘zgartirmasdan signallardan filtrlangan/saralangan massivni chiqaradi.
  • query/sortKey/sortDir: Ushbu signallarni UI dan yangilash orqali olingan ko‘rinishni boshqaring.
  • @for (p of view(); track p.name): Olingan qatorlarni ko‘rsatadi; identifikatsiya qilish uchun barqaror kalitdan (p.name) foydalanadi.
Eslatma: Shablonlarda og‘ir ishlardan saqlaning; andozalarni tez saqlash uchun computed() bilan oldindan hisoblash va @for bilan sikl.

W3Schools Pathfinder

Yutuqlaringizni kuzating – bu bepul!