Seri Angular 6+ cơ bản <P4> Hiển thị danh sách anh hùng

Hiển thị danh sách hero

Trong trang này, bạn sẽ mở rộng ứng dụng Tour of Heroes để hiển thị danh sách các hero và cho phép người dùng chọn một hero và hiển thị thông tin chi tiết về hero.

Tạo heroes giả.

Bạn sẽ cần một số hero để hiển thị.

Cuối cùng, bạn sẽ nhận được chúng từ một máy chủ dữ liệu từ xa. Hiện tại, bạn sẽ tạo một số hero giả và giả vờ rằng họ đến từ máy chủ.

Tạo một tệp có tên mock-heroes.ts trong thư mục src / app /. Xác định hằng số HEROES là một mảng gồm mười hero và xuất nó. Các tập tin sẽ trông như thế này.

// src/app/mock-heroes.ts

import { Hero } from './hero';

export const HEROES: Hero[] = [
  { id: 11, name: 'Mr. Nice' },
  { id: 12, name: 'Narco' },
  { id: 13, name: 'Bombasto' },
  { id: 14, name: 'Celeritas' },
  { id: 15, name: 'Magneta' },
  { id: 16, name: 'RubberMan' },
  { id: 17, name: 'Dynama' },
  { id: 18, name: 'Dr IQ' },
  { id: 19, name: 'Magma' },
  { id: 20, name: 'Tornado' }
];

Hiển thị hero

Bạn sắp hiển thị danh sách các hero ở đầu HeroesComponent. Mở tệp class HeroesComponent và import HEROES giả.
// src/app/heroes/heroes.component.ts (import HEROES)

import { HEROES } from '../mock-heroes';

Trong cùng một tệp (class HeroesComponent), xác định một thuộc tính thành phần được gọi là  heroes để hiển thị mảng HEROES để liên kết.

export class HeroesComponent implements OnInit {

  heroes = HEROES;

Liệt kê heroes với * ngFor

Mở tệp mẫu HeroesComponent và thực hiện các thay đổi sau:

  • Thêm một <h2> ở trên cùng,
  • Bên dưới, nó thêm một danh sách không có thứ tự HTML (<ul>)
  • Chèn <li> trong <ul> hiển thị các thuộc tính của hero.
  • Rắc một số lớp CSS để tạo style (bạn sẽ sớm thêm các kiểu CSS).

 

Làm cho nó trông như thế này:

// heroes.component.html (heroes template)

<h2>My Heroes</h2>
<ul class="heroes">
  <li>
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

Bây giờ thay đổi <li> thành này:

<li *ngFor="let hero of heroes">
 
* NgFor là directive lặp lại của Angular. Nó lặp lại phần tử máy chủ cho từng phần tử trong danh sách. Trong ví dụ này
  • <li> là thành phần máy chủ
  • heroes là danh sách từ lớp HeroesComponent.
  • hero giữ hero object hiện tại cho mỗi lần lặp thông qua danh sách.

Đừng quên dấu hoa thị (*) trước ngFor. Đây là một phần quan trọng của cú pháp.

Sau khi trình duyệt làm mới, danh sách các anh hùng xuất hiện.

Style the heroes

Danh sách hero phải hấp dẫn và sẽ phản hồi trực quan khi người dùng di chuột qua và chọn một hero từ danh sách.

Trong hướng dẫn đầu tiên, bạn đặt các style cơ bản cho toàn bộ ứng dụng trong style.css. Bản định kiểu đó không bao gồm các style cho danh sách hero này.

Bạn có thể thêm nhiều kiểu hơn vào style.css và tiếp tục phát triển biểu định style đó khi bạn thêm các thành phần.

Thay vào đó, bạn có thể thích xác định các style riêng tư cho một thành phần cụ thể và giữ mọi thứ mà một thành phần cần có mã Code, HTML và CSS.

Cách tiếp cận này giúp việc sử dụng lại thành phần ở một nơi khác dễ dàng hơn và mang lại diện mạo dự định của thành phần ngay cả khi các style toàn cục khác nhau.

Bạn xác định các style riêng hoặc là nội tuyến trong mảng @ Element.styles hoặc dưới dạng (các) tệp biểu định style được xác định trong mảng @ Element.styleUrls.

Khi CLI tạo HeroesComponent, nó đã tạo ra một bản định style hero.component.css trống cho HeroesComponent và chỉ vào nó trong @ Element.styleUrls như thế này.

// src/app/heroes/heroes.component.ts (@Component)

@Component({
  selector: 'app-heroes',
  templateUrl: './heroes.component.html',
  styleUrls: ['./heroes.component.css']
})
 
Mở tệp Heroes.component.css và dán theo kiểu CSS riêng cho HeroesComponent. Bạn sẽ tìm thấy chúng trong phần đánh giá mã cuối cùng ở cuối hướng dẫn này.

Style và stylesheets được xác định trong siêu dữ liệu @Component nằm trong phạm vi thành phần cụ thể đó. Các kiểu hero.component.css chỉ áp dụng cho HeroesComponent và không ảnh hưởng đến HTML bên ngoài hoặc HTML trong bất kỳ thành phần nào khác.

Chi tiết

Khi người dùng nhấp vào một hero trong danh sách chính, thành phần sẽ hiển thị chi tiết của hero được chọn ở cuối trang.

Trong phần này, bạn sẽ lắng nghe sự kiện click vào 1 hero và cập nhật chi tiết về hero.

Thêm một ràng buộc sự kiện click

Thêm một sự kiện click chuột ràng buộc vào <li> như thế này:
heroes.component.html (template excerpt)

<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
 
Đây là một ví dụ về cú pháp ràng buộc sự kiện của Angular.
Các dấu ngoặc đơn xung quanh click cho Angular lắng nghe sự kiện click của phần tử <li>. Khi người dùng click vào <li>, Angular sẽ thực thi biểu thức onSelect (hero).
onSelect () là một phương thức HeroesComponent mà bạn sắp viết. Angular gọi nó với đối tượng hero được hiển thị trong <li> đã click, cùng một hero được xác định trước đó trong biểu thức * ngFor.

Thêm trình xử lý sự kiện click

Đổi tên thuộc tính hero của thành phần thành selectedHero nhưng không gán nó. Không có hero được chọn khi ứng dụng bắt đầu.

Thêm phương thức onSelect () sau đây để gán hero được nhấp từ mẫu vào thành phần được chọn của thành phần.

src/app/heroes/heroes.component.ts (onSelect)

selectedHero: Hero;
onSelect(hero: Hero): void {
  this.selectedHero = hero;
}

Cập nhật mẫu chi tiết

Mẫu vẫn đề cập đến thuộc tính hero cũ của thành phần không còn tồn tại. Đổi tên hero thành selectedHero.

heroes.component.html (selected hero details)

<h2>{{selectedHero.name | uppercase}} Details</h2>
<div><span>id: </span>{{selectedHero.id}}</div>
<div>
  <label>name:
    <input [(ngModel)]="selectedHero.name" placeholder="name"/>
  </label>
</div>

Ẩn chi tiết trống với *ngIf

Sau khi trình duyệt làm mới, ứng dụng bị hỏng.
Mở các công cụ phát triển trình duyệt và tìm trong bảng điều khiển để tìm thông báo lỗi như thế này:
HeroesComponent.html:3 ERROR TypeError: Cannot read property 'name' of undefined

Bây giờ bấm vào một trong các mục danh sách. Các ứng dụng dường như đang hoạt động trở lại. Heroes xuất hiện trong một danh sách và chi tiết về hero được nhấp xuất hiện ở cuối trang.

Chuyện gì đã xảy ra?

Khi ứng dụng khởi động, selectedHero không xác định theo thiết kế.
Các biểu thức liên kết trong mẫu tham chiếu đến các thuộc tính của selectHero - các biểu thức như {{selectedHero.name}} - phải thất bại vì không có hero được chọn.

Cách khắc phục

Thành phần chỉ nên hiển thị các chi tiết hero được chọn nếu tồn tại selectedHero

Gói HTML chi tiết hero trong <div>. Thêm diretive * ngIf của Angular vào <div> và đặt nó thành selectedHero.

Đừng quên dấu hoa thị (*) trước ngIf. Đây là một phần quan trọng của cú pháp.
src/app/heroes/heroes.component.html (*ngIf)

<div *ngIf="selectedHero">

  <h2>{{selectedHero.name | uppercase}} Details</h2>
  <div><span>id: </span>{{selectedHero.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="selectedHero.name" placeholder="name"/>
    </label>
  </div>

</div>
 
Sau khi trình duyệt làm mới, danh sách các tên sẽ xuất hiện lại. Khu vực chi tiết trống. Nhấp vào một hero và chi tiết của nó xuất hiện.
Tại sao nó hoạt động?
Khi được selectedHero không được xác định, ng If sẽ xóa chi tiết hero khỏi DOM. Không có ràng buộc selectedHero nào để lo lắng về.
Khi người dùng chọn một hero, selectedHero có một giá trị và ngIf đưa chi tiết hero vào DOM.

Style cho hero được chọn

Thật khó để xác định hero được chọn trong danh sách khi tất cả các yếu tố <li> trông giống nhau. Nếu người dùng nhấp vào "Magneta", hero đó sẽ kết xuất với màu nền đặc biệt nhưng tinh tế như thế này:

 

 

 

 

Màu hero được chọn đó là công việc của lớp .selected CSS  trong các syle bạn đã thêm trước đó. Bạn chỉ cần áp dụng lớp .selected cho <li> khi người dùng nhấp vào nó.

Class binding của Angular giúp dễ dàng thêm và xóa lớp CSS một cách có điều kiện. Chỉ cần thêm [class.some-css-class] = "some-condition" vào thành phần bạn muốn tạo style

// heroes.component.html (toggle the 'selected' CSS class)

[class.selected]="hero === selectedHero"

Khi hàng hero hiện tại giống với người được chọn, Angular sẽ thêm lớp CSS được chọn. Khi hai hero khác nhau, Angular loại bỏ lớp . <Li> đã hoàn thành trông như thế này:

Thêm liên kết [class.selected] sau vào <li> trong mẫu HeroesComponent:

// heroes.component.html (list item hero)

<li *ngFor="let hero of heroes"
  [class.selected]="hero === selectedHero"
  (click)="onSelect(hero)">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

Đánh giá code cuối cùng

Ứng dụng của bạn sẽ giống như ví dụ trực tiếp.

Tổng kết

  • Ứng dụng Tour of Heroes hiển thị danh sách các anh hùng trong chế độ xem Master/Detail.
  • Người dùng có thể chọn một anh hùng và xem chi tiết của anh hùng đó.
  • Bạn đã sử dụng * ngFor để hiển thị danh sách.
  • Bạn đã sử dụng * ngIf có điều kiện bao gồm hoặc loại trừ một khối HTML.
  • Bạn có thể chuyển đổi một lớp style CSS với một ràng buộc lớp.

 

Nguồn:https://angular.io/tutorial/toh-pt2

Dịch bởi Vũ Đức Nguyên 

 

 

Hướng dẫn phối mầu trong thiết kế đồ họa Hướng dẫn phối mầu trong thiết kế đồ họa Techmaster team Blog Home Tương lai của lập trình website thân thiện Tương lai của lập trình website thân thiện Techmaster team
Hương Giang Idol