การสร้างองค์ประกอบแถบเลื่อนรูปภาพโดยใช้ Angular

การสร้างองค์ประกอบแถบเลื่อนรูปภาพโดยใช้ Angular

เกี่ยวกับ Codelab นี้

subjectอัปเดตล่าสุดเมื่อ ต.ค. 20, 2020
account_circleเขียนโดย aayush

1 บทนำ

ผู้เขียนโดย Aayush Arora

องค์ประกอบ Angular คือคอมโพเนนต์ Angular ที่บรรจุเป็นองค์ประกอบที่กําหนดเอง ปัจจุบัน Chrome OS, Opera และ Safari รองรับฟีเจอร์ดังกล่าว และมีให้บริการในเบราว์เซอร์อื่นผ่าน Polyfill องค์ประกอบเหล่านี้ใช้ประโยชน์จากโครงสร้างพื้นฐานของ Angular ทั้งหมดได้ด้วย Angular Interface และ Detection Strategy ที่พบบ่อย เมื่อลงทะเบียนแล้ว คุณจะใช้องค์ประกอบเหล่านี้ได้ในเบราว์เซอร์

Codelab นี้จะแนะนําการสร้างคอมโพเนนต์แบบเหลี่ยมมุมของแถบเลื่อนของคุณเอง และจะช่วยให้คุณเปลี่ยนรูปแบบเป็นองค์ประกอบแบบเหลี่ยมมุมเพื่อให้ทํางานนอกเฟรมเวิร์ก Angular ได้

สิ่งที่คุณจะสร้าง

ใน Codelab นี้ คุณจะสร้างองค์ประกอบแถบเลื่อนรูปภาพโดยใช้มุม องค์ประกอบของคุณกับ wi:

  • ทํางานเหมือนองค์ประกอบ HTML ในเบราว์เซอร์
  • เชื่อมต่อกับเฟรมเวิร์กใดก็ได้ที่คุยกับ DOM

สิ่งที่จะได้เรียนรู้

  • วิธีสร้างคอมโพเนนต์แถบเลื่อนที่กําหนดเอง
  • วิธีเปลี่ยนคอมโพเนนต์ที่กําหนดเองของแถบเลื่อนรูปภาพเป็นองค์ประกอบที่กําหนดเอง
  • วิธีจัดแพ็กเกจคอมโพเนนต์เพื่อให้ทํางานในเบราว์เซอร์

สิ่งที่ต้องมี

  • angular-cli เวอร์ชันใหม่ล่าสุด
  • โค้ดตัวอย่าง
  • เครื่องมือแก้ไขข้อความ
  • ความรู้พื้นฐานของคอมโพเนนต์ Angular

Codelab นี้มุ่งเน้นที่องค์ประกอบ Angular แนวคิดที่ไม่มีความเกี่ยวข้องและการบล็อกโค้ดจะไม่เพียงพอ และคุณก็มีหน้าที่คัดลอกและวางเท่านั้น

2 การเริ่มตั้งค่า

ดาวน์โหลดโค้ด

คลิกลิงก์ต่อไปนี้เพื่อดาวน์โหลดโค้ดทั้งหมดสําหรับ Codelab นี้:

คลายการคลายไฟล์ ZIP ที่ดาวน์โหลด การดําเนินการนี้จะเปิดเผยโฟลเดอร์รูท (angular-element-codelab-master) ซึ่งประกอบด้วย

2 โฟลเดอร์ (image-slider) และ (image-slider-finished) โดยเราจะทําการเขียนโค้ดทั้งหมดในไดเรกทอรีที่เรียกว่าแถบเลื่อนรูปภาพ

การดําเนินโครงการ

หากต้องการเรียกใช้โปรเจ็กต์ คุณต้องเรียกใช้คําสั่ง ( ng-serve ) จากไดเรกทอรีราก ( image-slider)

เมื่อบูตแอปแล้ว คุณจะเห็นรายการต่อไปนี้

ไฟล์ 19ffd082e2f024a5.png

3 การสร้างคอมโพเนนต์ที่กําหนดเองของแถบเลื่อนรูปภาพ

วิธีสร้างแถบเลื่อนรูปภาพ

สําหรับแถบเลื่อนรูปภาพนี้ ปุ่มเชื่อมโยงโดยใช้การเชื่อมโยงการคลิกแบบเหลี่ยมมุม เราจะสร้างอาร์เรย์ของออบเจ็กต์ที่มีรูปภาพ แท็ก Alt ลิงก์ ฯลฯ เราจะวางรูปภาพเหล่านี้ไว้ด้านล่างๆ ในคอนเทนเนอร์ และแปลคอนเทนเนอร์เมื่อคลิก

เราจะสร้างคอมโพเนนต์แถบเลื่อนรูปภาพเพื่อเปลี่ยนรูปแบบเป็นองค์ประกอบแบบเหลี่ยมมุม

  • คอนเทนเนอร์สําหรับรูปภาพและชื่อ
  • อาร์เรย์ที่มีข้อมูล
  • เทมเพลตเพื่อเชื่อมโยงข้อมูล

4 ใช้คอมโพเนนต์แถบเลื่อนรูปภาพ

สําหรับการเริ่มต้นทําโครงการใดๆ ได้หลายวิธี วิธีที่เราทําให้โครงการของเราเรียบง่ายที่สุดและเน้นที่องค์ประกอบ Angular เราได้ให้รหัสพื้นฐานแก่คุณพร้อมกับ CSS

การสร้างอาร์เรย์และบริการข้อมูล

แถบเลื่อนคือแถบเลื่อนที่มี

  • คีย์ img สําหรับ URL ของรูปภาพในแถบเลื่อน
  • แท็ก Alt เพื่อระบุ Alt ของรูปภาพ
  • ข้อความที่จะให้คําอธิบายเกี่ยวกับรูปภาพ

ไฟล์ data.json ที่อยู่ในไดเรกทอรี src/assets ควรมีลักษณะดังนี้

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'}
];

เราต้องดึงข้อมูลนี้ในคอมโพเนนต์โดยใช้บริการ ในไฟล์ data.service.ts เราจะเขียนเมธอด getData() โดยใช้โมดูล httpClient จาก @angular/common/http ซึ่งจะดึงข้อมูลจากอาร์เรย์ที่เราสร้างไว้ข้างต้น

 
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)
 
}
}

การดึงข้อมูลจากบริการข้อมูล

เราต้องนําเข้าบริการของเราภายในคอมโพเนนต์เพื่อให้เราสมัครรับข้อมูลที่สังเกตได้เพื่อรับออบเจ็กต์จาก data.json

เราจําเป็นต้องดําเนินการ 3 ขั้นตอนดังนี้

  • การเริ่มต้นอาร์เรย์คอมโพเนนต์
  • การสมัครใช้บริการ"การสังเกตการณ์"ที่แสดงผลโดยฟังก์ชัน getData()
  • สร้างผลลัพธ์ของอินเทอร์เฟซสําหรับการตรวจสอบประเภทข้อมูลหลังจากติดตามที่สังเกตได้
  • กําหนดข้อมูลให้กับอาร์เรย์คอมโพเนนต์

กําลังเริ่มต้นอาร์เรย์คอมโพเนนต์

เราจะประกาศและเริ่มอาร์เรย์ของคอมโพเนนต์ภายใน slider.component.ts ที่เป็นอาร์เรย์ของออบเจ็กต์

วิธีประกาศ

sliderArray: object[];

วิธีเริ่มต้น

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

ถัดไป เราต้องนําเข้าและเริ่มต้นบริการของเราภายในเครื่องมือสร้าง

constructor(private data: DataService) {}

ตอนนี้เราพร้อมจะเริ่มใช้งานบริการของเราและโทรหาบริการจากบริการของเราแล้ว

การรับข้อมูลจากบริการข้อมูล

เพื่อให้ได้ข้อมูลออกจากบริการ เราจะเรียกใช้เมธอด getData() และสมัครรับข้อมูลที่สังเกตได้ว่าจะส่งคืนกลับมา เราจะสร้างอินเทอร์เฟซ Result, ด้วย เพื่อที่เราจะพิมพ์กําลังตรวจสอบว่าเราได้รับข้อมูลที่ถูกต้อง

เราจะดําเนินการภายใน ngOnInit เมธอด:

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

การกําหนดข้อมูลให้กับอาร์เรย์คอมโพเนนต์

ในตอนท้าย เราจะกําหนดข้อมูลให้แก่อาร์เรย์คอมโพเนนต์

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

เมื่อเราได้รับข้อมูลภายในอาร์เรย์ของคอมโพเนนต์แล้ว เราจะเชื่อมโยงเทมเพลตของเรากับข้อมูลนี้ได้

ใน slider.component.html, เรามีเทมเพลต HTML อยู่แล้ว ขั้นตอนถัดไปคือเชื่อมโยงเทมเพลตนี้กับ sliderArray

5 การเชื่อมโยงข้อมูลกับเทมเพลต

เราจะเชื่อมโยงข้อมูลกับเทมเพลตโดยใช้คําสั่ง *ngFor และสุดท้าย เราจะเพิ่มการเปลี่ยนรูปแบบในเทมเพลตเพื่อให้แถบเลื่อนทํางาน

ซึ่งมี 3 ขั้นตอนดังนี้

  • เชื่อมโยง sliderArray กับเทมเพลต
  • การเพิ่มการเชื่อมโยงเหตุการณ์สําหรับปุ่มแถบเลื่อน
  • การเพิ่มการเปลี่ยนรูปแบบ CSS โดยใช้ ngStyle และ ngClass

การเชื่อมโยงสไลด์ Array กับคอมโพเนนต์

เรามีคอนเทนเนอร์ที่มี img-container, a text-container และ a slider.

เราจะเชื่อมโยงข้อมูลในคอนเทนเนอร์ทั้ง 3 รายการโดยใช้คําสั่ง *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>

การเชื่อมโยงเหตุการณ์กับ สไลด์Array

เมื่อมีการเชื่อมโยงข้อมูล เราจะเชื่อมโยงเหตุการณ์การคลิกกับปุ่มสไลด์ทุกปุ่มโดยใช้ click binding แบบเหลี่ยม เราจะสร้างฟังก์ชันชื่อ selected(x) โดยที่ x คือดัชนีของอาร์เรย์

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;
 
}
}

ข้อควรจําที่นี่

  • ฟังก์ชันที่ดาวน์เกรดจะลดค่าของพร็อพเพอร์ตี้"เปลี่ยนรูปแบบ"ไป 50 เท่าเมื่อดัชนีที่ส่งผ่านเมื่อคลิกของฟังก์ชัน selected
  • ตรรกะนี้จะแปลงคอนเทนเนอร์ข้อความเป็น 100%, 50%, -50%, -100% ซึ่งส่งผลให้เกิด 4 สถานะที่แตกต่างกัน

การเพิ่มการแปลง CSS โดยใช้ ngStyle & ngClass

ในตอนเริ่มต้น เราตั้งค่ารูปภาพทั้งหมดความทึบแสงเป็น 0 โดยเราจะเพิ่มคลาส selected โดยใช้ ngClass directive เมื่อดัชนีที่เลือกเท่ากับดัชนีรูปภาพ คลาส selected นี้เพิ่มความทึบแสงของ 1 ให้แก่รูปภาพ ซึ่งจะทําให้ผู้ใช้เห็นรูปภาพได้

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

หลังจากนั้น เราจะแปลคอนเทนเนอร์ข้อความตามค่า transform ที่คํานวณโดยใช้ฟังก์ชัน select()

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

เมื่อทําตามขั้นตอนทั้งหมดแล้ว คุณจะดูรหัสสุดท้ายได้ที่ด้านล่าง

<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 การเปลี่ยนคอมโพเนนต์เป็นองค์ประกอบมุมเหลี่ยม

ซึ่งประกอบด้วย 5 ขั้นตอนดังนี้

  • การใช้ Shadow DOM สําหรับองค์ประกอบมุมเหลี่ยม
  • ใช้ประโยชน์จาก entryComponents
  • กําลังนําเข้าและใช้โมดูล CreateCustomElement จาก @angular/elements
  • คําจํากัดความเรื่อง custom-element
  • ใช้เมธอด ngDoBootstrap

การใช้ Shadow DOM สําหรับองค์ประกอบแบบเหลี่ยม

ตอนนี้เราต้องมีแถบเลื่อนรูปภาพ ก็แค่ต้องทําให้เป็น Angular Element แทน

ส่วนที่สนุกก็คือจะมีการเปลี่ยนแปลงเพียงเล็กน้อยในการสร้าง DOM ของคอมโพเนนต์ซึ่งเป็น Shadow DOM

เราต้องนําเข้าโมดูล ViewEncapsulation และต้องใช้เมธอด ShadowDom จากโมดูลดังกล่าว

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

การใช้EntryComponents

คอมโพเนนต์รายการคือคอมโพเนนต์ที่โหลดแบบเหลี่ยมโดยไม่จําเป็น คุณระบุคอมโพเนนต์รายการได้โดยการเปิดเครื่องใน NgModule

เราจะระบุ SliderComponent ในอาร์เรย์ entryComponents ภายใน @NgModule

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

การนําเข้าและใช้โมดูล createCustomElement

ในที่นี้จะต้องใช้โมดูล createCustomElement จาก @angular/elements. และต้องใช้ SliderComponent, เป็นพารามิเตอร์ของฟังก์ชัน createCustomElement หลังจากนั้น เราต้องลงทะเบียน slider ใน DOM

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

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

หากต้องการบันทึกแถบเลื่อนเป็นองค์ประกอบ DOM เราจะกําหนดแถบเลื่อนโดยใช้เมธอด customElements.define

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

สุดท้าย เราต้องบูตเอลิเมนต์ที่กําหนดเองนี้โดยใช้เมธอด ngDoBootstrap() โค้ดที่สมบูรณ์จะมีลักษณะดังนี้

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
() {}

}

การบรรจุองค์ประกอบเชิงมุม

เราจําเป็นต้องแก้ไข package.json ด้วยคําสั่งใหม่ เราจะแก้ไขออบเจ็กต์สคริปต์ภายในไฟล์ package.json

มาตรวจสอบออบเจ็กต์สคริปต์ที่แก้ไขของเรากัน

"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"
}

ตอนนี้เราจะเรียกใช้คําสั่ง ng build & ng package แล้วสุดท้ายเราจะเรียกใช้ ng display เพื่อแสดง Dist/ โฟลเดอร์ที่สร้างขึ้นโดยใช้คําสั่ง build นอกจากนี้ เรายังใช้ gzip ที่ได้รับจากคําสั่ง ng package, แยกออกมา และเผยแพร่เป็น npm module ได้