Xây dựng phần tử thanh trượt hình ảnh bằng Angular

Xây dựng phần tử thanh trượt hình ảnh bằng Angular

Thông tin về lớp học lập trình này

subjectLần cập nhật gần đây nhất: thg 10 20, 2020
account_circleTác giả: aayush

1. Giới thiệu

Tác giả khách Aayush Arora

Thành phần Angular là Thành phần Angular được đóng gói dưới dạng thành phần tùy chỉnh. Hiện tại, Chrome hỗ trợ Chrome, Opera và Safari trên các trình duyệt khác thông qua polyfill. Các thành phần này có thể tận dụng toàn bộ Cơ sở hạ tầng Angular với Giao diện Angular và Chiến lược phát hiện thay đổi phổ biến. Sau khi đăng ký, bạn có thể sử dụng các thành phần này trong trình duyệt.

Lớp học lập trình này sẽ hướng dẫn bạn tạo thành phần góc thanh trượt hình ảnh của riêng mình, sau đó sẽ giúp bạn chuyển đổi thành một phần tử góc để nó có thể hoạt động bên ngoài Khung Angular.

Sản phẩm bạn sẽ tạo ra

Trong lớp học lập trình này, bạn sẽ tạo một phần tử thanh trượt hình ảnh bằng cách sử dụng góc. Phần tử của bạn:

  • hoạt động giống như một phần tử HTML trong trình duyệt
  • Có thể cắm vào bất kỳ khung nào trò chuyện với DOM.

Kiến thức bạn sẽ học được

  • Cách tạo thành phần tùy chỉnh thanh trượt hình ảnh
  • Cách chuyển đổi thành phần tùy chỉnh thanh trượt hình ảnh thành phần tử tùy chỉnh
  • Cách đóng gói để thành phần hoạt động bên trong trình duyệt

Bạn cần có

  • Phiên bản gần đây của angular-cli.
  • Mã mẫu
  • Trình chỉnh sửa văn bản
  • Kiến thức cơ bản về Thành phần Angular

Lớp học lập trình này tập trung vào các phần tử Angular. Các khái niệm và khối mã không liên quan sẽ được tô bóng và được cung cấp để bạn chỉ cần sao chép và dán.

2. Thiết lập

Tải mã nguồn xuống

Nhấp vào đường liên kết sau đây để tải toàn bộ mã nguồn cho lớp học lập trình này:

Giải nén tệp zip đã tải xuống. Thao tác này sẽ giải nén thư mục gốc (angular-element-codelab-master), trong đó có chứa

hai thư mục (image-slider)(image-slider-finished). Chúng tôi sẽ thực hiện tất cả công việc mã hóa trong thư mục có tên là thanh trượt hình ảnh.

Chạy dự án

Để chạy dự án, bạn cần chạy lệnh ( ng-serve ) từ thư mục gốc ( image-thanh ).

Sau khi ứng dụng được khởi động, bạn sẽ có thể thấy điều này:

19ffd082e2f024a5.png

3. Tạo thành phần tùy chỉnh cho Thanh trượt hình ảnh?

Làm cách nào để tạo thanh trượt hình ảnh?

Đối với thanh trượt hình ảnh này, hãy liên kết các nút bằng cách dùng liên kết nhấp chuột góc. Chúng ta sẽ tạo một mảng các đối tượng chứa hình ảnh, thẻ alt, đường liên kết, v.v. Chúng ta sẽ đặt những hình ảnh này bên dưới nhau trong vùng chứa và dịch khi vùng chứa được nhấp vào.

Chúng ta sẽ tạo một thành phần thanh trượt hình ảnh và sau đó sẽ chuyển đổi thành phần tử góc.

  • Vùng chứa dành cho hình ảnh và tiêu đề.
  • Một mảng chứa dữ liệu
  • Mẫu liên kết dữ liệu

4. Triển khai thành phần thanh trượt hình ảnh

Có nhiều cách để bắt đầu với mọi dự án. Trong trường hợp này, để giữ cho dự án của chúng tôi đơn giản nhất có thể và tập trung vào các thành phần Angular, chúng tôi đã cung cấp cho bạn mã cơ bản cùng với css.

Tạo một mảng và dịch vụ dữ liệu

Xin nhớ,{3}Array sẽ chứa:

  • Phím img cho URL hình ảnh trong thanh trượt
  • Thẻ alt để cung cấp alt cho hình ảnh
  • Văn bản để cung cấp mô tả về hình ảnh

Tệp data.json đã có trong thư mục src/assets của bạn sẽ có dạng như sau.

sliderArray = [
 
{img: 'http://bloquo.cc/img/works/1.jpg', alt: '', text: '365 Days Of weddings a year'},
 
{img: 'http://bloquo.cc/img/works/2.jpg', alt: '',  text: '365 Days Of weddings a year'},
 
{img: 'http://bloquo.cc/img/works/3.jpg', alt: '', text: '365 Days Of weddings a year'},
 
{img: 'http://bloquo.cc/img/works/4.jpg', alt: '',  text: '365 Days Of weddings a year'},
 
{img: 'http://bloquo.cc/img/works/5.jpg', alt: '', text: '365 Days Of weddings a year'}
];

Chúng ta cần tìm nạp dữ liệu này trong thành phần của mình bằng một dịch vụ. Trong tệp data.service.ts, chúng ta sẽ viết phương thức getData() bằng mô-đun httpClient của @angular/common/http. Mô-đun này sẽ tìm nạp dữ liệu từ mảng mà chúng ta đã tạo ở trên.

 
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'

const URL = '../assets/data.json';

@Injectable({
 providedIn
: 'root'
})
export class DataService {

 constructor
(private http: HttpClient) {}

 getData
() {
   
return this.http.get(URL)
 
}
}

Tìm nạp dữ liệu từ dịch vụ dữ liệu

Chúng ta cần nhập dịch vụ của mình vào thành phần, sau đó chúng ta có thể đăng ký đối tượng phát ra dữ liệu để lấy đối tượng từ data.json

Chúng tôi cần thực hiện ba bước để thực hiện việc này:

  • Khởi tạo một mảng thành phần
  • Đăng ký hàm có thể quan sát được do hàm getData() trả về
  • Tạo một Kết quả giao diện để kiểm tra loại dữ liệu sau khi đăng ký đối tượng phát ra dữ liệu.
  • Chỉ định dữ liệu cho mảng thành phần.

Đang khởi chạy mảng thành phần

Chúng ta sẽ khai báo và khởi tạo mảng thành phần bên trong slider.component.ts, là một mảng các đối tượng:

Cách khai báo:

sliderArray: object[];

Cách khởi chạy:

constructor(private data: DataService) {
 
this.sliderArray = [];
}

Tiếp theo, chúng ta cần nhập và khởi tạo dịch vụ của mình trong hàm dựng

constructor(private data: DataService) {}

Bây giờ, chúng ta đã sẵn sàng sử dụng dịch vụ của mình và gọi các phương thức dịch vụ.

Nhận dữ liệu từ Dịch vụ dữ liệu

Để nhận dữ liệu từ dịch vụ, chúng tôi sẽ gọi phương thức getData() và đăng ký đối tượng phát ra dữ liệu mà phương thức này sẽ trả về. Chúng tôi cũng sẽ tạo một giao diện Result,để có thể nhập dữ liệu nhằm kiểm tra xem chúng tôi có nhận được dữ liệu chính xác hay không.

Chúng ta sẽ thực hiện việc này bên trong phương thức ngOnInit:

this.data.getData().subscribe((result: Result)=>{
})

Chỉ định dữ liệu cho Mảng thành phần

Cuối cùng, chúng ta sẽ chỉ định dữ liệu cho mảng thành phần:

this.data.getData().subscribe((result: Result)=>{  
 
this.sliderArray = result.sliderArray;
})

Khi nhận được dữ liệu bên trong mảng thành phần, chúng ta có thể liên kết mẫu với dữ liệu này.

Trong slider.component.html,, chúng ta đã có một mẫu HTML. Bước tiếp theo của chúng ta là liên kết mẫu này với sliderArray.

5. Liên kết dữ liệu với mẫu

Chúng ta sẽ liên kết dữ liệu với mẫu bằng cách dùng Chỉ thị *ngFor và cuối cùng sẽ thêm các phép biến đổi trong mẫu để thanh trượt hoạt động.

Quy trình này bao gồm 3 bước:

  • Liên kết sliderArray với mẫu
  • Thêm Liên kết sự kiện cho các nút trên thanh trượt
  • Thêm các lượt chuyển đổi css bằng ngStylengClass

Liên kết trượtArray với thành phần

Chúng tôi có một vùng chứa chứa img-container, a text-containera slider.

Chúng ta sẽ liên kết dữ liệu trong cả 3 vùng chứa bằng cách dùng lệnh *ngFor

<div class="container">
 
<div class="img-container" *ngFor="let i of sliderArray; let select = index;">
   
<img src="{{i.img}}" alt="{{i.alt}}" >
 
</div>

 
<div>
   
<div class="text-container">
     
<div class="page-text" *ngFor="let i of sliderArray;let select = index;">
       
<h3>{{i.text}}</h3>
     
</div>
   
</div>
 
</div>

</div>

<div class="slider">
 
<div class="slide-button-parent-container" *ngFor="let i of sliderArray; let x =index">
   
<div class="select-box">
     
<div class="slide-button">
     
</div>
   
</div>
 
</div>
</div>

Liên kết sự kiện với trượtArray

Sau khi dữ liệu được liên kết, chúng ta sẽ liên kết sự kiện lượt nhấp với mọi nút trang trình bày bằng cách sử dụng click binding theo góc. Chúng ta sẽ tạo một hàm có tên là selected(x)trong đó x là chỉ mục của mảng.

selected(x) {
 
this.downSelected(x);
 
this.selectedIndex = x;
}

downSelected
(i) {
 
this.transform =  100 - (i) * 50;
 
this.selectedIndex = this.selectedIndex + 1;
 
if(this.selectedIndex > 4) {
   
this.selectedIndex = 0;
 
}
}

Những điểm cần nhớ ở đây:

  • Hàm đã chọn thấp hơn làm giảm giá trị của thuộc tính chuyển đổi xuống 50 lần chỉ mục được chuyển khi nhấp vào hàm selected.
  • Logic này chuyển vùng chứa văn bản thành 100%, 50%, -50%, -100% dẫn đến bốn trạng thái khác nhau.

Thêm các lượt chuyển đổi CSS bằng ngStyle & ngClass

Ban đầu, chúng tôi đặt tất cả hình ảnh, ở độ mờ bằng 0, chúng tôi thêm một lớp selected bằng ngClass directive khi chỉ mục được chọn trở thành bằng với chỉ mục hình ảnh. Lớp selected này thêm độ mờ của một ảnh vào hình ảnh để người dùng có thể thấy hình ảnh đó.

<div class="img-container"  *ngFor="let i of sliderArray; let select = index;"
      [
ngClass]="{'selected': select == selectedIndex}">
</div>

Sau đó, chúng ta sẽ dịch vùng chứa văn bản theo giá trị transform được tính bằng hàm select().

<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
</div>

Sau khi thực hiện tất cả các bước này, bạn có thể tìm ra mã cuối cùng như được cung cấp bên dưới:

<div class="container">
 
<div class="img-container"  *ngFor="let i of sliderArray; let select = index;"
      [
ngClass]="{'selected': select == selectedIndex}">
   
<img src="{{i.img}}" alt="{{i.alt}}" >
 
</div>

 
<!--</div>-->
 
<div [ngStyle]="{'transform': 'translateY('+ transform + '%' +')', 'transition': '.8s'}">
   
<div class="text-container">
     
<div class="page-text" *ngFor="let i of sliderArray;let select = index;" [ngClass]="{'selected': select == selectedIndex}">
       
<h3>{{i.text}}</h3>
     
</div>
   
</div>
 
</div>

</div>

<div class="slider">
 
<div class="slide-button-parent-container"  *ngFor="let i of sliderArray; let x =index" (click)="selected(x)" >
   
<div class="select-box">
     
<div   class="slide-button" [ngClass]="{'slide-button-select': x == selectedIndex}" >
     
</div>
   
</div>
 
</div>
</div>

6. Biến đổi thành phần thành phần tử góc

Quy trình này gồm có 5 bước:

  • Dùng Shadow DOM cho Phần tử góc
  • Sử dụng entryComponents
  • Đang nhập và sử dụng mô-đun CreateCustomElement của @angular/elements
  • Xác định custom-element của chúng tôi
  • Đang chạy phương thức ngDoBootstrap

Sử dụng DOM tối để làm phần tử góc

Bây giờ, chúng ta đã chạy thanh trượt hình ảnh, chúng ta chỉ cần đặt thanh trượt này thành Angular Element.

Phần thú vị là chỉ có một thay đổi nhỏ để tạo DOM thành phần, một DOM tối.

Chúng ta cần nhập mô-đun ViewEncapsulation và phải sử dụng phương thức ShadowDom từ mô-đun đó.

@Component({
 selector
: 'app-slider',
 templateUrl
: './slider.component.html',
 styleUrls
: ['./slider.component.css'],
 encapsulation
: ViewEncapsulation.ShadowDom
})

Khai thác mục Thành phần

Thành phần mục nhập là thành phần tải góc một cách bắt buộc. Bạn chỉ định một thành phần mục nhập bằng cách khởi động thành phần đó trong Ngmodule.

Ở đây, chúng ta sẽ chỉ định SliderComponent trong mảng entryComponents bên trong @NgModule

@NgModule({
 declarations
: [
   
SliderComponent
 
],
 imports
: [
   
BrowserModule,
   
HttpClientModule
 
],
 entryComponents
: [SliderComponent],
})

Nhập và sử dụng mô-đun CreateCustomElement

Ở đây, chúng ta cần dùng Mô-đun createCustomElement của @angular/elements.. Bạn cần dùng SliderComponent, làm thông số cho hàm createCustomElement. Sau đó, chúng ta cần đăng ký slider trong DOM.

import { createCustomElement } from '@angular/elements';

export class AppModule {
 constructor
(private injector: Injector) {
   
const slider = createCustomElement(SliderComponent, { injector });
   
}
}

Để đăng ký thanh trượt dưới dạng phần tử DOM, chúng tôi sẽ xác định thanh trượt bằng phương thức customElements.define.

customElements.define('motley-slider', slider);

Cuối cùng, chúng ta phải khởi động phần tử tùy chỉnh này bằng phương thức ngDoBootstrap(). Mã đầy đủ sẽ có dạng như sau:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { SliderComponent } from './slider/slider.component';
import { HttpClientModule} from "@angular/common/http";

@NgModule({
 declarations
: [
   
SliderComponent
 
],
 imports
: [
   
BrowserModule,
   
HttpClientModule
 
],
 entryComponents
: [SliderComponent],
})
export class AppModule {
 constructor
(private injector: Injector) {
   
const slider = createCustomElement(SliderComponent, { injector });
   customElements
.define('motley-slider', slider);
 
}

 ngDoBootstrap
() {}

}

Đóng gói phần tử Angular

Chúng ta cần sửa đổi package.json bằng các lệnh mới, chúng ta sẽ sửa đổi đối tượng tập lệnh bên trong tệp package.json.

Hãy kiểm tra đối tượng tập lệnh được sửa đổi của chúng ta:

"scripts": {
 
"ng": "ng",
 
"start": "ng serve",
 
"build": "ng build --prod --output-hashing=none",
 
"package": "cat dist/my-app/{runtime,polyfills,scripts,main}.js | gzip > elements.js.gz",
 
"serve": "http-server",
 
"test": "ng test",
 
"lint": "ng lint",
 
"e2e": "ng e2e"
}

Bây giờ, chúng ta có thể chạy lệnh ng build & ng package và cuối cùng chúng ta sẽ chạy ng phân phối để phân phát thư/phân phối được tạo bằng lệnh bản dựng. Ngoài ra, chúng ta có thể dùng gzip lấy từ lệnh ng package, trích xuất lệnh đó và có thể xuất bản lệnh đó dưới dạng npm module.