لمحة عن هذا الدرس التطبيقي حول الترميز
1. مقدمة
بقلم مؤلف الضيف Aayush Arora
العناصر المتماثلة هي مكوّنات Angular مجمّعة كعناصر مخصّصة. وهي متوافقة حاليًا مع Chrome وOpera وSafari وهي متاحة في متصفحات أخرى من خلال polyfills. ويمكن أن تستفيد هذه العناصر من البنية الأساسية ذات الزاوية دائمًا مع الواجهة الزاوية الشائعة واستراتيجية اكتشاف التغيير. بعد تسجيل العناصر، يمكن استخدامها في المتصفّح.
سيرشدك هذا الدرس التطبيقي إلى خطوات إنشاء مكوّن الزاوية المزوّد بشريط تمرير، ويساعدك بعد ذلك على تحويله إلى عنصر زاوي حتى يمكنه العمل خارج إطار عمل Angular.
البنية التي ستنشئها
في هذا الدرس التطبيقي حول الترميز، ستنشئ عنصرًا شريط تمرير الصور باستخدام الزاوية. العنصر مع:
|
ما ستتعرّف عليه
- كيفية إنشاء مكوّن مخصّص لشريط تمرير الصور
- كيفية تحويل المكوِّن المخصص لشريط تمرير الصورة إلى عنصر مخصص
- كيفية تجميع المكوِّن بحيث يعمل داخل المتصفح
المتطلبات اللازمة
- إصدار حديث من angular-cli.
- نموذج الرمز
- محرِّر نصوص
- المعرفة الأساسية بالمكوّنات الزاوية
يركّز هذا الدرس التطبيقي على عناصر Angular. يتم معقل المفاهيم وقوالب الرموز غير ذات الصلة وتوفيرها لك لنسخها ولصقها.
2. البدء في الإعداد
تنزيل الرمز
انقر على الرابط التالي لتنزيل كل رموز هذا الدرس التطبيقي حول الترميز:
فك ضغط ملف zip الذي تم تنزيله. سيؤدي ذلك إلى فك ضغط المجلد الجذر (angular-element-codelab-master)
الذي يحتوي على
مجلدان (image-slider)
و(image-slider-finished)
سنجري جميع أعمال الترميز في دليل يُسمى "شريط تمرير الصور".
تنفيذ المشروع
لتنفيذ المشروع، عليك تنفيذ الأمر ( ng-serve ) من الدليل الجذري ( image-slider).
بعد تشغيل التطبيق، ستتمكن من رؤية ما يلي:
3. هل تريد إنشاء مكوِّن مخصّص لشريط تمرير الصور؟
كيفية إنشاء شريط تمرير الصور
بالنسبة إلى شريط تمرير الصور هذا، يمكنك ربط الأزرار باستخدام رابط النقر مع الزاوية. سننشئ مجموعة من العناصر التي تحتوي على صور وعلامات بديلة وروابط وما إلى ذلك. وسنضع هذه الصور واحدة تلو الأخرى في حاوية ونترجم الحاوية عند النقر.
سننشئ مكوّنًا لمزلق الصور ثم سنحوّله إلى عنصر بزاوية.
- حاوية الصور والعناوين
- مصفوفة تحتوي على البيانات
- نموذج لإلزام البيانات
4. تنفيذ مكوّن شريط تمرير الصور
هناك طرق متعددة لبدء استخدام أي مشروع، في هذه الحالة، للحفاظ على مشروعنا بسيطًا قدر الإمكان والتركيز على العناصر Angular، لقد وفرنا لك الرمز الأساسي مع خدمة مقارنة الأسعار.
إنشاء مصفوفة وخدمة بيانات
ملاحظة: ستحتوي شريط التمرير على:
- مفتاح img لعنوان URL للصورة في شريط التمرير
- علامة النص البديل لتقديم بديل للصورة
- نص لتقديم وصف حول الصورة
يجب أن يظهر الملف 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
.
يجب تنفيذ ثلاث خطوات لإجراء ذلك:
- إعداد مصفوفة مكوّن
- الاشتراك في الملاحظة القابلة للملاحظة التي تعرضها دالة
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
، وأخيرًا سنضيف إحالات ناجحة في النموذج حتى يعمل شريط التمرير.
ويتألف ذلك من ثلاث خطوات:
- ربط
sliderArray
بالنموذج - إضافة رابط الأحداث لأزرار شريط التمرير
- إضافة تحويلات css باستخدام
ngStyle
وngClass
ربط SegmentArray بالمكون
لدينا حاوية تتضمن 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;
}
}
نقاط يجب أخذها في الاعتبار:
- تقلل الدالة المحدّدة من قيمة الإحالة الناجحة من خمسين مرة يمر بها الفهرس عند النقر على دالة
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. تحويل المكوِّن إلى العنصر الزاوي
يتألف هذا الإجراء من خمس خطوات:
- استخدام
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
})
الاستفادة من InputComponents
مكوّن الإدخال هو مكوّن يتم تحميله باستخدام الزوايا بشكل ضروري. يمكنك تحديد مكوِّن إدخال من خلال تشغيله في وحدة NgModule.
سنحدد هنا SliderComponent
في المصفوفة entryComponents
داخل @NgModule
@NgModule({
declarations: [
SliderComponent
],
imports: [
BrowserModule,
HttpClientModule
],
entryComponents: [SliderComponent],
})
استيراد وحدة CreateCustomElement واستخدامها
في هذه الحالة، يجب استخدام وحدة createCustomElement
من @angular/elements.
. ويجب استخدام SliderComponent,
كمعلَمة مع دالة createCustomElement
. بعد ذلك، علينا تسجيل slider
في نموذج العناصر في المستند.
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 service لعرض Dist/ folder الذي يتم إنشاؤه باستخدام أمر build. يمكننا أيضًا استخدام gzip
التي تم الحصول عليها من الأمر ng package
واستخراجها ونشرها npm module
.