1. परिचय
मेहमान लेखक आयुष अरोड़ा ने लिखा
Angular Elements, Angular कॉम्पोनेंट होते हैं. इन्हें कस्टम एलिमेंट के तौर पर पैकेज किया जाता है. फ़िलहाल, ये Chrome, Opera, और Safari पर काम करते हैं. साथ ही, ये पॉलीफ़िल के ज़रिए अन्य ब्राउज़र पर भी उपलब्ध हैं. ये एलिमेंट, सामान्य ऐंगुलर इंटरफ़ेस और बदलाव का पता लगाने की रणनीति के साथ, पूरे ऐंगुलर इन्फ़्रास्ट्रक्चर का इस्तेमाल कर सकते हैं. रजिस्टर होने के बाद, इन एलिमेंट का इस्तेमाल ब्राउज़र में किया जा सकता है.
इस कोडलैब में, आपको इमेज-स्लाइडर वाला अपना एंगुलर कॉम्पोनेंट बनाने का तरीका बताया जाएगा. इसके बाद, इसे एंगुलर एलिमेंट में बदलने का तरीका बताया जाएगा, ताकि यह एंगुलर फ़्रेमवर्क के बाहर भी काम कर सके.
आपको क्या बनाना है
| 
 | 
| इस कोडलैब में, Angular का इस्तेमाल करके इमेज-स्लाइडर एलिमेंट बनाया जाएगा. आपका एलिमेंट wi: 
 | 
आपको क्या सीखने को मिलेगा
- इमेज-स्लाइडर कस्टम कॉम्पोनेंट बनाने का तरीका
- इमेज-स्लाइडर कस्टम कॉम्पोनेंट को कस्टम एलिमेंट में कैसे बदलें
- कॉम्पोनेंट को इस तरह से पैकेज करना कि वह ब्राउज़र में काम करे
आपको इन चीज़ों की ज़रूरत होगी
- angular-cli का नया वर्शन.
- सैंपल कोड
- टेक्स्ट एडिटर
- Angular कॉम्पोनेंट की बुनियादी जानकारी
यह कोडलैब, Angular Elements पर आधारित है. इसमें काम के न होने वाले कॉन्सेप्ट और कोड ब्लॉक को हटा दिया जाता है. साथ ही, इन्हें सिर्फ़ कॉपी और चिपकाने के लिए उपलब्ध कराया जाता है.
2. सेट अप करना
कोड डाउनलोड करें
इस कोडलैब के लिए पूरा कोड डाउनलोड करने के लिए, यहां दिए गए लिंक पर क्लिक करें:
डाउनलोड की गई ज़िप फ़ाइल को अनपैक करें. इससे रूट फ़ोल्डर (angular-element-codelab-master) अनपैक हो जाएगा. इसमें ये चीज़ें शामिल हैं
दो फ़ोल्डर (image-slider) और (image-slider-finished). हम कोडिंग से जुड़ा सारा काम, image-slider नाम की डायरेक्ट्री में करेंगे.
प्रोजेक्ट को लागू करना
प्रोजेक्ट चलाने के लिए, आपको रूट डायरेक्ट्री ( image-slider ) से कमांड ( ng-serve ) चलाना होगा.
ऐप्लिकेशन बूटस्ट्रैप होने के बाद, आपको यह दिखेगा:

3. क्या आपको इमेज-स्लाइडर कस्टम कॉम्पोनेंट बनाना है ?
इमेज स्लाइडर कैसे बनाएं?
इस इमेज स्लाइडर के लिए, ऐंगुलर क्लिक बाइंडिंग का इस्तेमाल करके बटन बाइंड करें. हम इमेज, ऑल्ट टैग, लिंक वगैरह वाले ऑब्जेक्ट का एक कलेक्शन बनाएंगे. हम इन इमेज को एक कंटेनर में एक के नीचे एक रखेंगे. इसके बाद, क्लिक करने पर कंटेनर का अनुवाद करेंगे.
हम एक इमेज-स्लाइडर कॉम्पोनेंट बनाएंगे. इसके बाद, उसे ऐंगुलर-एलिमेंट में बदल देंगे.
- इमेज और टाइटल के लिए कंटेनर.
- डेटा वाली एक सरणी
- डेटा को बाइंड करने के लिए टेंप्लेट
4. इमेज-स्लाइडर कॉम्पोनेंट लागू करना
किसी भी प्रोजेक्ट को शुरू करने के कई तरीके होते हैं. इस मामले में, हमने अपने प्रोजेक्ट को जितना हो सके उतना आसान रखने और Angular Elements पर ध्यान देने के लिए, आपको सीएसएस के साथ-साथ बुनियादी कोड भी उपलब्ध कराया है.
ऐरे और डेटा सेवा बनाना
याद रखें कि sliderArray में यह जानकारी शामिल होगी:
- स्लाइडर में मौजूद इमेज के यूआरएल के लिए img कुंजी
- इमेज के लिए वैकल्पिक टेक्स्ट देने वाला ऑल्ट टैग
- इमेज के बारे में जानकारी देने के लिए टेक्स्ट
आपकी src/assets डायरेक्ट्री में मौजूद data.json फ़ाइल कुछ ऐसी दिखनी चाहिए.
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 में, हम @angular/common/http से httpClient मॉड्यूल का इस्तेमाल करके getData() तरीके को लिखेंगे. यह तरीका, ऊपर बनाए गए ऐरे से डेटा फ़ेच करेगा.
 
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()फ़ंक्शन से मिले Observable की सदस्यता लेना
- ऑब्ज़र्वेबल की सदस्यता लेने के बाद, डेटा की टाइप-चेकिंग के लिए 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)=>{
})
कॉम्पोनेंट ऐरे को डेटा असाइन करना
आखिर में, हम डेटा को कॉम्पोनेंट ऐरे में असाइन करेंगे:
this.data.getData().subscribe((result: Result)=>{  
  this.sliderArray = result.sliderArray;
})
जब हमें अपने कॉम्पोनेंट की ऐरे में डेटा मिल जाता है, तब हम अपने टेंप्लेट को इस डेटा से बाइंड कर सकते हैं.
slider.component.html, में हमारे पास पहले से ही एक एचटीएमएल टेंप्लेट है. अगले चरण में, हमें इस टेंप्लेट को sliderArray से बाइंड करना है.
5. डेटा को टेंप्लेट के साथ बाइंड करना
हम *ngFor डायरेक्टिव का इस्तेमाल करके, डेटा को टेंप्लेट से बाइंड करेंगे. इसके बाद, हम टेंप्लेट में ट्रांसफ़ॉर्मेशन जोड़ेंगे, ताकि स्लाइडर काम कर सके.
इसमें तीन चरण शामिल हैं:
- sliderArrayको टेंप्लेट से बाइंड करना
- स्लाइडर बटन के लिए इवेंट बाइंडिंग जोड़ना
- 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;
  }
}
इन बातों का ध्यान रखें:
- चुने गए फ़ंक्शन में, ट्रांसफ़ॉर्म प्रॉपर्टी की वैल्यू को selectedफ़ंक्शन पर क्लिक करने पर पास किए गए इंडेक्स से 50 गुना कम किया जाता है.
- इस लॉजिक से टेक्स्ट कंटेनर को 100%, 50%, -50%, -100% पर ट्रांसलेट किया जाता है. इससे चार अलग-अलग स्थितियां मिलती हैं.
ngStyle और ngClass का इस्तेमाल करके सीएसएस ट्रांसफ़ॉर्म जोड़ना
शुरुआत में, हम सभी इमेज को ओपैसिटी शून्य पर सेट करते हैं. जब चुना गया इंडेक्स, इमेज इंडेक्स के बराबर हो जाता है, तब हम selected क्लास को ngClass directive का इस्तेमाल करके जोड़ते हैं. यह selected क्लास, इमेज में एक की ओपैसिटी जोड़ता है. इससे इमेज, उपयोगकर्ता को दिखती है.
<div class="img-container"  *ngFor="let i of sliderArray; let select = index;"
      [ngClass]="{'selected': select == selectedIndex}">
</div>
इसके बाद, हम select() फ़ंक्शन का इस्तेमाल करके कैलकुलेट की गई transform वैल्यू के हिसाब से, टेक्स्ट-कंटेनर का अनुवाद करेंगे.
<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का इस्तेमाल करना
- @angular/elementsसे- CreateCustomElementमॉड्यूल इंपोर्ट करना और उसका इस्तेमाल करना
- अपने custom-elementको तय करना
- ngDoBootstrapतरीका
ऐंगलर एलिमेंट के लिए शैडो डीओएम का इस्तेमाल करना
अब हमारा इमेज-स्लाइडर काम कर रहा है. हमें इसे सिर्फ़ Angular Element बनाना है.
सबसे मज़ेदार बात यह है कि कॉम्पोनेंट डीओएम को शैडो डीओएम बनाने के लिए, सिर्फ़ मामूली बदलाव करना पड़ता है.
हमें ViewEncapsulation मॉड्यूल को इंपोर्ट करना होगा और इसमें से ShadowDom तरीके का इस्तेमाल करना होगा.
@Component({
 selector: 'app-slider',
 templateUrl: './slider.component.html',
 styleUrls: ['./slider.component.css'],
 encapsulation: ViewEncapsulation.ShadowDom
})
entryComponents का इस्तेमाल करना
एंट्री कॉम्पोनेंट, एक ऐसा कॉम्पोनेंट होता है जिसे Angular, ज़रूरी तौर पर लोड करता है. किसी एंट्री कॉम्पोनेंट को NgModule में बूटस्ट्रैप करके, उसे तय किया जाता है.
यहां हम @NgModule में मौजूद entryComponents कलेक्शन में अपना SliderComponent तय करेंगे
@NgModule({
 declarations: [
   SliderComponent
 ],
 imports: [
   BrowserModule,
   HttpClientModule
 ]
})
createCustomElement मॉड्यूल को इंपोर्ट करना और उसका इस्तेमाल करना
यहां, हमें @angular/elements. से createCustomElement मॉड्यूल का इस्तेमाल करना होगा. आपको createCustomElement फ़ंक्शन के पैरामीटर के तौर पर SliderComponent, का इस्तेमाल करना होगा. इसके बाद, हमें DOM में 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
 ]
})
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 कमांड चलाएंगे, ताकि build कमांड का इस्तेमाल करके जनरेट किए गए dist/ फ़ोल्डर को दिखाया जा सके. इसके अलावा, हम ng package कमांड से मिले gzip का इस्तेमाल कर सकते हैं. साथ ही, इसे निकालकर npm module के तौर पर पब्लिश कर सकते हैं.
