ساخت یک عنصر اسلایدر تصویر با استفاده از Angular

1. مقدمه

توسط نویسنده مهمان Aayush Arora

عناصر زاویه ای، اجزای زاویه ای هستند که به عنوان عناصر سفارشی بسته بندی شده اند. آنها در حال حاضر توسط کروم، اپرا و سافاری پشتیبانی می شوند و در مرورگرهای دیگر از طریق polyfills در دسترس هستند. این عناصر می توانند از کل زیرساخت زاویه ای با رابط مشترک زاویه ای و استراتژی تشخیص تغییر استفاده کنند. پس از ثبت نام، این عناصر می توانند در مرورگر استفاده شوند.

این لبه کد شما را در ایجاد مولفه زاویه‌ای اسلایدر تصویر راهنمایی می‌کند و سپس به شما کمک می‌کند تا آن را به یک عنصر زاویه‌ای تبدیل کنید تا بتواند خارج از چارچوب زاویه‌ای کار کند.

آنچه را که خواهید ساخت

در این کد لبه، شما قصد دارید یک عنصر اسلایدر تصویر را با استفاده از angular بسازید. عنصر شما با:

  • مانند یک عنصر HTML در مرورگر کار کنید
  • قادر به اتصال به هر چارچوبی که با DOM صحبت می کند.

چیزی که یاد خواهید گرفت

  • چگونه یک کامپوننت سفارشی اسلایدر تصویر بسازیم
  • چگونه مولفه سفارشی تصویر اسلایدر را به عنصر سفارشی تبدیل کنیم
  • چگونه کامپوننت را بسته بندی کنیم تا در داخل مرورگر کار کند

آنچه شما نیاز دارید

این کد لبه روی عناصر زاویه ای متمرکز شده است. مفاهیم و بلوک‌های کد غیرمرتبط محو شده‌اند و برای شما ارائه می‌شوند تا به سادگی کپی و جای‌گذاری کنید.

2. راه اندازی

کد را دانلود کنید

برای دانلود تمامی کدهای این کد لبه روی لینک زیر کلیک کنید:

فایل فشرده دانلود شده را باز کنید. با این کار یک پوشه ریشه (angular-element-codelab-master) که حاوی است باز می شود

دو پوشه (image-slider) و (image-slider-finished) . ما تمام کارهای کدنویسی خود را در دایرکتوری به نام image-slider انجام خواهیم داد.

اجرای پروژه

برای اجرای پروژه، باید دستور (ng-serve) را از دایرکتوری ریشه (image-slider) اجرا کنید.

هنگامی که برنامه بوت استرپ شد، می توانید این را ببینید:

19ffd082e2f024a5.png

3. ساخت یک جزء سفارشی Image-Slider؟

چگونه یک اسلایدر تصویر ایجاد کنیم؟

برای این نوار لغزنده تصویر، دکمه‌ها را با استفاده از اتصال کلیکی زاویه‌ای متصل کنید. ما یک آرایه از اشیاء حاوی تصاویر، تگ‌های alt، پیوندها و غیره ایجاد خواهیم کرد. این تصاویر را یکی زیر هم در یک ظرف قرار می‌دهیم و ظرف را با کلیک ترجمه می‌کنیم.

ما می خواهیم یک مولفه تصویر-لغزنده ایجاد کنیم و سپس آن را به عنصر زاویه ای تبدیل می کنیم.

  • ظرفی برای تصاویر و عناوین.
  • آرایه ای حاوی داده ها
  • الگویی برای اتصال داده ها

4. مولفه image-slider را پیاده سازی کنید

راه های مختلفی برای شروع هر پروژه ای وجود دارد، در این مورد، برای ساده نگه داشتن پروژه خود و تمرکز بر روی عناصر 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

برای این کار باید سه مرحله را انجام دهیم:

  • راه اندازی یک آرایه جزء
  • اشتراک در تابع Observable که توسط getData() برگردانده شده است
  • ایجاد یک نتیجه واسط برای بررسی نوع داده ها پس از اشتراک در مشاهده پذیر.
  • داده ها را به آرایه مؤلفه اختصاص دهید.

راه اندازی آرایه کامپوننت

آرایه مؤلفه را در داخل slider.component.ts که آرایه ای از اشیاء است، اعلام و مقداردهی اولیه می کنیم:

اعلام:

sliderArray: object[];

برای مقداردهی اولیه:

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

در مرحله بعد، باید سرویس خود را در سازنده وارد و مقداردهی اولیه کنیم

constructor(private data: DataService) {}

اکنون، ما آماده استفاده از خدمات خود و فراخوانی روش های خدمات خود هستیم.

دریافت داده از سرویس داده

برای دریافت داده‌ها از سرویس، getData() را فراخوانی می‌کنیم و مشترک مشاهداتی می‌شویم که برمی‌گردد، همچنین یک Interface Result, ایجاد می‌کنیم تا بتوانیم چک کنیم که داده‌های صحیح را دریافت می‌کنیم.

ما این کار را در متد ngOnInit انجام خواهیم داد:

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

تخصیص داده به Component Array

در پایان، داده ها را به آرایه مؤلفه اختصاص می دهیم:

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

هنگامی که داده ها را در داخل آرایه مؤلفه خود دریافت کردیم، می توانیم الگوی خود را با این داده ها پیوند دهیم.

در slider.component.html, ما قبلا یک قالب HTML داریم. گام بعدی ما پیوند این الگو با sliderArray است.

5. اتصال داده ها با الگو

داده‌ها را با استفاده از *ngFor Directive با الگو پیوند می‌دهیم و در نهایت تبدیل‌هایی را در قالب اضافه می‌کنیم تا اسلایدر کار کند.

این شامل سه مرحله است:

  • اتصال sliderArray به الگو
  • اضافه کردن رویداد Binding برای دکمه‌های لغزنده
  • افزودن تبدیل های css با استفاده از ngStyle و ngClass

اتصال slideArray به کامپوننت

ما یک ظرف حاوی یک کانتینر img-container ، a محفظه text-container و a slider.

ما داده ها را در هر سه کانتینر با استفاده از دستور *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>

اتصال رویداد به slideArray

هنگامی که داده ها متصل شد، رویداد کلیک را با استفاده از 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;
  }
}

نکاتی که باید در اینجا به خاطر بسپارید:

  • تابع downsected مقدار ویژگی تبدیل را پنجاه برابر شاخص ارسال شده با کلیک روی تابع selected کاهش می دهد.
  • این منطق ظرف متن را به 100٪، 50٪، -50٪، -100٪ ترجمه می کند که منجر به چهار حالت مختلف می شود.

افزودن تبدیل های CSS با استفاده از ngStyle و ngClass

در ابتدا همه تصاویر را با کدورت صفر تنظیم می کنیم، زمانی که شاخص انتخاب شده با شاخص تصویر برابر شود، کلاسی را که با استفاده از ngClass directive selected شده است، اضافه می کنیم. این کلاس selected کدورت یک را به تصویر اضافه می کند و تصویر را برای کاربر قابل مشاهده می کند.

<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. تبدیل جزء به عنصر زاویه ای

این روش شامل پنج مرحله است:

  • استفاده از Shadow DOM برای عنصر زاویه ای
  • استفاده از entryComponents های ورودی
  • وارد کردن و استفاده از ماژول CreateCustomElement از @angular/elements
  • تعریف custom-element ما
  • اجرای روش ngDoBootstrap

استفاده از Shadow DOM برای عنصر زاویه ای

اکنون اسلایدر تصویر خود را در حال اجرا داریم، فقط باید آن را به یک Angular Element تبدیل کنیم.

بخش سرگرم کننده این است که، فقط یک تغییر جزئی برای ساختن مولفه DOM، یک DOM سایه وجود دارد.

ما باید ماژول ViewEncapsulation را وارد کنیم و باید از روش ShadowDom از آن استفاده کنیم.

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

استفاده از کامپوننت های ورودی

کامپوننت ورودی مولفه ای است که بارهای زاویه ای به طور ضروری انجام می شود. شما یک جزء ورودی را با راه‌اندازی آن در NgModule مشخص می‌کنید.

در اینجا، entryComponents SliderComponent @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 serve را برای سرویس‌دهی پوشه dist/ تولید شده با استفاده از دستور build اجرا می‌کنیم. همچنین، می‌توانیم از gzip به‌دست‌آمده از دستور ng package استفاده کنیم، آن را استخراج کنیم و بتوانیم آن را به عنوان یک npm module منتشر کنیم.