1. مقدمة
بقلم الضيف أيوش أرورا
عناصر Angular هي مكوّنات Angular مجمّعة كعناصر مخصّصة. وهي متوافقة حاليًا مع Chrome وOpera وSafari، وتتوفّر في المتصفّحات الأخرى من خلال polyfills. يمكن أن تستفيد هذه العناصر من بنية Angular الأساسية الكاملة مع واجهة Angular الشائعة واستراتيجية رصد التغيير. بعد التسجيل، يمكن استخدام هذه العناصر داخل المتصفّح.
سيرشدك هذا الدرس العملي خلال عملية إنشاء مكوّن Angular الخاص بك لشريط تمرير الصور، ثم سيساعدك في تحويله إلى عنصر Angular لكي يعمل خارج إطار عمل Angular.
ما ستنشئه
في هذا الدرس العملي، ستنشئ عنصرًا لعرض شرائح الصور باستخدام Angular. Your element wi:
|
ما ستتعرّف عليه
- كيفية إنشاء مكوّن مخصّص لشريط تمرير الصور
- كيفية تحويل المكوّن المخصّص image-slider إلى عنصر مخصّص
- كيفية تجميع المكوّن ليعمل داخل المتصفّح
المتطلبات
- إصدار حديث من angular-cli
- الرمز النموذجي
- محرّر نصوص
- معرفة أساسية بمكوّنات Angular
يركّز هذا الدرس التطبيقي حول الترميز على Angular Elements. يتم تجاهل المفاهيم وكتل الرموز غير ذات الصلة، ويتم توفيرها لك لنسخها ولصقها ببساطة.
2. الإعداد
تنزيل الرمز
انقر على الرابط التالي لتنزيل كل الرموز البرمجية لهذا الدرس العملي:
فكّ ضغط ملف ZIP الذي تم تنزيله. سيؤدي ذلك إلى فك ضغط مجلد جذري (angular-element-codelab-master)
يحتوي على
مجلدان (image-slider)
و(image-slider-finished)
سننفّذ جميع أعمال الترميز في دليل باسم image-slider.
تشغيل المشروع
لتشغيل المشروع، عليك تنفيذ الأمر ( ng-serve ) من الدليل الجذر ( image-slider ).
بعد إعداد التطبيق، سيظهر لك ما يلي:
3- Making an Image-Slider custom component ?
كيفية إنشاء شريط تمرير للصور؟
بالنسبة إلى شريط تمرير الصور هذا، اربط الأزرار باستخدام ربط النقر الزاوي. سننشئ مجموعة من العناصر التي تحتوي على صور وعلامات نص بديل وروابط وما إلى ذلك. وسنضع هذه الصور واحدة أسفل الأخرى في حاوية ونترجم الحاوية عند النقر عليها.
سننشئ مكوّنًا منزلقًا للصور، ثم سنحوّله إلى عنصر Angular.
- حاوية للصور والعناوين
- مصفوفة تحتوي على البيانات
- نموذج لربط البيانات
4. تنفيذ مكوّن شريط تمرير الصور
هناك طرق متعددة للبدء في أي مشروع، وفي هذه الحالة، للحفاظ على بساطة مشروعنا قدر الإمكان والتركيز على Angular Elements، قدّمنا لك رمزًا أساسيًا مع CSS.
إنشاء مصفوفة وخدمة بيانات
تذكَّر أنّ sliderArray سيتضمّن ما يلي:
- مفتاح img لعنوان URL الخاص بالصورة في شريط التمرير
- علامة 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()
- أنشئ واجهة Result للتحقّق من نوع البيانات بعد الاشتراك في العنصر القابل للمراقبة.
- خصِّص البيانات لمصفوفة المكوّن.
تهيئة مصفوفة المكوّنات
سنعرّف مصفوفة المكوّنات ونبدأها داخل slider.component.ts
التي هي مصفوفة من العناصر:
لتقديم إقرار ضريبي، اتّبِع الخطوات التالية:
sliderArray: object[];
لإجراء الإعداد الأوّلي، اتّبِع الخطوات التالية:
constructor(private data: DataService) {
this.sliderArray = [];
}
بعد ذلك، علينا استيراد خدمتنا وتهيئتها داخل الدالة الإنشائية
constructor(private data: DataService) {}
الآن، نحن على استعداد لاستخدام خدمتنا واستدعاء طرق الخدمة.
الحصول على بيانات من "خدمة البيانات"
للحصول على البيانات من الخدمة، سنستدعي الطريقة getData()
ونشترك في العنصر القابل للمراقبة الذي سيتم إرجاعه، وسننشئ أيضًا واجهة 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
، وأخيرًا سنضيف عمليات تحويل في النموذج لتشغيل شريط التمرير.
يتضمّن ذلك ثلاث خطوات:
- ربط
sliderArray
بالقالب - إضافة ربط الأحداث لأزرار شريط التمرير
- إضافة تحويلات 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
بعد ربط البيانات، سنربط حدث النقر بكل زر من أزرار الشرائح باستخدام Angular 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;
}
}
في ما يلي بعض النقاط التي يجب تذكُّرها:
- تؤدي الدالة التي تم اختيارها إلى خفض قيمة خاصية التحويل بمقدار خمسين مرة من الفهرس الذي تم تمريره عند النقر على الدالة
selected
. - تؤدي هذه العملية إلى ترجمة حاوية النص إلى %100 و%50 و-50% و-100%، ما يؤدي إلى أربع حالات مختلفة.
إضافة عمليات تحويل CSS باستخدام ngStyle وngClass
في البداية، نضبط جميع الصور على مستوى عتامة يساوي صفرًا، ثم نضيف فئة selected
باستخدام ngClass directive
عندما يصبح الفهرس المحدّد مساويًا لفهرس الصورة. تضيف فئة 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. تحويل المكوّن إلى عنصر Angular
يتألف هذا الإجراء من خمس خطوات:
- استخدام
Shadow DOM
لعنصر Angular - الاستفادة من
entryComponents
- استيراد وحدة
CreateCustomElement
واستخدامها من@angular/elements
- تحديد
custom-element
- طريقة
ngDoBootstrap
استخدام Shadow DOM لعنصر Angular
بعد أن أصبح لدينا شريط تمرير الصور يعمل، ما علينا سوى تحويله إلى Angular Element
.
الجزء الممتع هو أنّه لا يوجد سوى تغيير بسيط لجعل مكوّن DOM، وهو shadow DOM.
علينا استيراد الوحدة ViewEncapsulation
واستخدام الطريقة ShadowDom
منها.
@Component({
selector: 'app-slider',
templateUrl: './slider.component.html',
styleUrls: ['./slider.component.css'],
encapsulation: ViewEncapsulation.ShadowDom
})
الاستفادة من entryComponents
Entry Component هو مكوّن يتم تحميله بشكل إلزامي في Angular. يمكنك تحديد مكوّن إدخال من خلال إعداده في NgModule.
سنحدّد هنا SliderComponent
في مصفوفة entryComponents
داخل @NgModule
@NgModule({
declarations: [
SliderComponent
],
imports: [
BrowserModule,
HttpClientModule
]
})
استيراد وحدة 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
]
})
export class AppModule {
constructor(private injector: Injector) {
const slider = createCustomElement(SliderComponent, { injector });
customElements.define('motley-slider', slider);
}
ngDoBootstrap() {}
}
تغليف عنصر Angular
علينا تعديل 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
.