# बैंकिंग ऐप बनाएं भाग 1: HTML टेम्पलेट्स और वेब ऐप में रूट्स
## प्री-लेक्चर क्विज़
[प्री-लेक्चर क्विज़](https://ff-quizzes.netlify.app/web/quiz/41)
### परिचय
ब्राउज़रों में जावास्क्रिप्ट के आगमन के बाद से, वेबसाइटें पहले से कहीं अधिक इंटरएक्टिव और जटिल हो गई हैं। वेब तकनीकों का उपयोग अब पूरी तरह से कार्यात्मक एप्लिकेशन बनाने के लिए किया जाता है जो सीधे ब्राउज़र में चलते हैं, जिन्हें हम [वेब एप्लिकेशन](https://en.wikipedia.org/wiki/Web_application) कहते हैं। चूंकि वेब ऐप्स अत्यधिक इंटरएक्टिव होते हैं, उपयोगकर्ता हर बार किसी क्रिया के प्रदर्शन पर पूरे पेज को रीलोड करने की प्रतीक्षा नहीं करना चाहते। यही कारण है कि जावास्क्रिप्ट का उपयोग HTML को सीधे DOM के माध्यम से अपडेट करने के लिए किया जाता है, ताकि उपयोगकर्ता अनुभव को अधिक सहज बनाया जा सके।
इस पाठ में, हम HTML टेम्पलेट्स का उपयोग करके कई स्क्रीन बनाने की नींव रखेंगे, जिन्हें पूरे HTML पेज को रीलोड किए बिना प्रदर्शित और अपडेट किया जा सकता है।
### पूर्वापेक्षा
इस पाठ में हम जो वेब ऐप बनाएंगे उसे टेस्ट करने के लिए आपको एक लोकल वेब सर्वर की आवश्यकता होगी। यदि आपके पास एक नहीं है, तो आप [Node.js](https://nodejs.org) इंस्टॉल कर सकते हैं और अपने प्रोजेक्ट फ़ोल्डर से `npx lite-server` कमांड का उपयोग कर सकते हैं। यह एक लोकल वेब सर्वर बनाएगा और आपके ऐप को ब्राउज़र में खोलेगा।
### तैयारी
अपने कंप्यूटर पर `bank` नामक एक फ़ोल्डर बनाएं और उसमें `index.html` नामक एक फ़ाइल रखें। हम इस HTML [बॉयलरप्लेट](https://en.wikipedia.org/wiki/Boilerplate_code) से शुरुआत करेंगे:
```html
Bank App
```
---
## HTML टेम्पलेट्स
यदि आप वेब पेज के लिए कई स्क्रीन बनाना चाहते हैं, तो एक समाधान यह होगा कि आप प्रत्येक स्क्रीन के लिए एक HTML फ़ाइल बनाएं जिसे आप प्रदर्शित करना चाहते हैं। हालांकि, इस समाधान में कुछ असुविधाएं हैं:
- स्क्रीन स्विच करते समय पूरे HTML को रीलोड करना पड़ता है, जो धीमा हो सकता है।
- विभिन्न स्क्रीन के बीच डेटा साझा करना कठिन होता है।
एक अन्य दृष्टिकोण यह है कि केवल एक HTML फ़ाइल हो और `` एलिमेंट का उपयोग करके कई [HTML टेम्पलेट्स](https://developer.mozilla.org/docs/Web/HTML/Element/template) परिभाषित किए जाएं। एक टेम्पलेट एक पुन: उपयोग योग्य HTML ब्लॉक है जिसे ब्राउज़र द्वारा प्रदर्शित नहीं किया जाता और इसे रनटाइम पर जावास्क्रिप्ट का उपयोग करके इंस्टैंसिएट करना पड़ता है।
### कार्य
हम एक बैंक ऐप बनाएंगे जिसमें दो स्क्रीन होंगी: लॉगिन पेज और डैशबोर्ड। सबसे पहले, HTML बॉडी में एक प्लेसहोल्डर एलिमेंट जोड़ें जिसे हम अपने ऐप की विभिन्न स्क्रीन इंस्टैंसिएट करने के लिए उपयोग करेंगे:
```html
Loading...
```
हम इसे जावास्क्रिप्ट के साथ बाद में ढूंढने में आसानी के लिए एक `id` दे रहे हैं।
> टिप: चूंकि इस एलिमेंट की सामग्री बदली जाएगी, हम इसमें एक लोडिंग संदेश या संकेतक डाल सकते हैं जो ऐप लोड होने के दौरान दिखाया जाएगा।
अब, लॉगिन पेज के लिए HTML टेम्पलेट को नीचे जोड़ें। फिलहाल हम इसमें केवल एक शीर्षक और एक सेक्शन डालेंगे जिसमें एक लिंक होगा जिसका उपयोग हम नेविगेशन करने के लिए करेंगे।
```html
Bank App
```
फिर हम डैशबोर्ड पेज के लिए एक और HTML टेम्पलेट जोड़ेंगे। इस पेज में विभिन्न सेक्शन होंगे:
- एक हेडर जिसमें एक शीर्षक और लॉगआउट लिंक होगा
- बैंक खाते का वर्तमान बैलेंस
- लेन-देन की सूची, जो एक टेबल में प्रदर्शित होगी
```html
```
> टिप: जब HTML टेम्पलेट्स बना रहे हों, यदि आप देखना चाहते हैं कि यह कैसा दिखेगा, तो आप `` और `` लाइनों को `` के साथ घेरकर कमेंट कर सकते हैं।
✅ आपको क्या लगता है कि हम टेम्पलेट्स पर `id` एट्रिब्यूट्स का उपयोग क्यों करते हैं? क्या हम कुछ और जैसे क्लासेस का उपयोग कर सकते हैं?
## जावास्क्रिप्ट के साथ टेम्पलेट्स प्रदर्शित करना
यदि आप अपने वर्तमान HTML फ़ाइल को ब्राउज़र में आज़माते हैं, तो आप देखेंगे कि यह `Loading...` दिखाने पर अटक जाती है। ऐसा इसलिए है क्योंकि हमें HTML टेम्पलेट्स को इंस्टैंसिएट और प्रदर्शित करने के लिए कुछ जावास्क्रिप्ट कोड जोड़ने की आवश्यकता है।
टेम्पलेट को इंस्टैंसिएट करना आमतौर पर 3 चरणों में किया जाता है:
1. DOM में टेम्पलेट एलिमेंट को प्राप्त करें, उदाहरण के लिए [`document.getElementById`](https://developer.mozilla.org/docs/Web/API/Document/getElementById) का उपयोग करके।
2. टेम्पलेट एलिमेंट को क्लोन करें, [`cloneNode`](https://developer.mozilla.org/docs/Web/API/Node/cloneNode) का उपयोग करके।
3. इसे DOM में एक दृश्यमान एलिमेंट के तहत अटैच करें, उदाहरण के लिए [`appendChild`](https://developer.mozilla.org/docs/Web/API/Node/appendChild) का उपयोग करके।
✅ हमें टेम्पलेट को DOM में अटैच करने से पहले क्लोन करने की आवश्यकता क्यों है? यदि हम इस चरण को छोड़ दें तो क्या होगा?
### कार्य
अपने प्रोजेक्ट फ़ोल्डर में `app.js` नामक एक नई फ़ाइल बनाएं और उस फ़ाइल को अपने HTML के `` सेक्शन में इंपोर्ट करें:
```html
```
अब `app.js` में, हम एक नया फंक्शन `updateRoute` बनाएंगे:
```js
function updateRoute(templateId) {
const template = document.getElementById(templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
```
यहां हम ठीक वही 3 चरण करते हैं जो ऊपर वर्णित हैं। हम `templateId` के साथ टेम्पलेट को इंस्टैंसिएट करते हैं और इसके क्लोन किए गए कंटेंट को हमारे ऐप प्लेसहोल्डर में डालते हैं। ध्यान दें कि हमें पूरे सबट्री को कॉपी करने के लिए `cloneNode(true)` का उपयोग करना होगा।
अब इस फंक्शन को किसी एक टेम्पलेट के साथ कॉल करें और परिणाम देखें।
```js
updateRoute('login');
```
✅ इस कोड `app.innerHTML = '';` का उद्देश्य क्या है? इसके बिना क्या होता है?
## रूट्स बनाना
जब वेब ऐप की बात होती है, तो हम *रूटिंग* को **URLs** को विशिष्ट स्क्रीन से मैप करने का इरादा कहते हैं जो प्रदर्शित की जानी चाहिए। कई HTML फ़ाइलों वाली वेबसाइट पर, यह स्वचालित रूप से किया जाता है क्योंकि फ़ाइल पथ URL पर प्रतिबिंबित होते हैं। उदाहरण के लिए, आपके प्रोजेक्ट फ़ोल्डर में ये फ़ाइलें होने पर:
```
mywebsite/index.html
mywebsite/login.html
mywebsite/admin/index.html
```
यदि आप `mywebsite` को रूट के रूप में वेब सर्वर बनाते हैं, तो URL मैपिंग होगी:
```
https://site.com --> mywebsite/index.html
https://site.com/login.html --> mywebsite/login.html
https://site.com/admin/ --> mywebsite/admin/index.html
```
हालांकि, हमारे वेब ऐप के लिए हम एक ही HTML फ़ाइल का उपयोग कर रहे हैं जिसमें सभी स्क्रीन हैं, इसलिए यह डिफ़ॉल्ट व्यवहार हमारी मदद नहीं करेगा। हमें इस मैप को मैन्युअल रूप से बनाना होगा और जावास्क्रिप्ट का उपयोग करके प्रदर्शित टेम्पलेट को अपडेट करना होगा।
### कार्य
हम एक साधारण ऑब्जेक्ट का उपयोग करेंगे [मैप](https://en.wikipedia.org/wiki/Associative_array) को लागू करने के लिए जो URL पथ और हमारे टेम्पलेट्स के बीच संबंध बनाएगा। इस ऑब्जेक्ट को अपने `app.js` फ़ाइल के शीर्ष पर जोड़ें।
```js
const routes = {
'/login': { templateId: 'login' },
'/dashboard': { templateId: 'dashboard' },
};
```
अब `updateRoute` फंक्शन को थोड़ा संशोधित करें। सीधे `templateId` को आर्ग्युमेंट के रूप में पास करने के बजाय, हम पहले वर्तमान URL को देखकर इसे प्राप्त करना चाहते हैं, और फिर हमारे मैप का उपयोग करके संबंधित टेम्पलेट ID मान प्राप्त करना चाहते हैं। हम [`window.location.pathname`](https://developer.mozilla.org/docs/Web/API/Location/pathname) का उपयोग करके URL से केवल पथ सेक्शन प्राप्त कर सकते हैं।
```js
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
const template = document.getElementById(route.templateId);
const view = template.content.cloneNode(true);
const app = document.getElementById('app');
app.innerHTML = '';
app.appendChild(view);
}
```
यहां हमने घोषित रूट्स को संबंधित टेम्पलेट से मैप किया। आप इसे आज़मा सकते हैं कि यह सही ढंग से काम करता है या नहीं, ब्राउज़र में URL को मैन्युअल रूप से बदलकर।
✅ यदि आप URL में एक अज्ञात पथ दर्ज करते हैं तो क्या होता है? हम इसे कैसे हल कर सकते हैं?
## नेविगेशन जोड़ना
हमारे ऐप का अगला चरण पेजों के बीच नेविगेट करने की संभावना जोड़ना है, बिना URL को मैन्युअल रूप से बदलने के। इसमें दो चीजें शामिल हैं:
1. वर्तमान URL को अपडेट करना
2. नए URL के आधार पर प्रदर्शित टेम्पलेट को अपडेट करना
हमने पहले ही `updateRoute` फंक्शन के साथ दूसरे भाग का ध्यान रखा है, इसलिए हमें यह पता लगाना होगा कि वर्तमान URL को कैसे अपडेट किया जाए।
हमें जावास्क्रिप्ट का उपयोग करना होगा और विशेष रूप से [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) का उपयोग करना होगा जो URL को अपडेट करने और ब्राउज़िंग हिस्ट्री में एक नया एंट्री बनाने की अनुमति देता है, बिना HTML को रीलोड किए।
> नोट: जबकि HTML एंकर एलिमेंट [``](https://developer.mozilla.org/docs/Web/HTML/Element/a) का उपयोग अपने आप विभिन्न URLs के लिए हाइपरलिंक्स बनाने के लिए किया जा सकता है, यह डिफ़ॉल्ट रूप से HTML को रीलोड कर देगा। कस्टम जावास्क्रिप्ट के साथ रूटिंग को संभालते समय इस व्यवहार को रोकना आवश्यक है, `preventDefault()` फंक्शन का उपयोग करके क्लिक इवेंट पर।
### कार्य
आइए एक नया फंक्शन बनाएं जिसे हम अपने ऐप में नेविगेट करने के लिए उपयोग कर सकते हैं:
```js
function navigate(path) {
window.history.pushState({}, path, path);
updateRoute();
}
```
यह मेथड पहले दिए गए पथ के आधार पर वर्तमान URL को अपडेट करता है, फिर टेम्पलेट को अपडेट करता है। प्रॉपर्टी `window.location.origin` URL रूट को रिटर्न करती है, जिससे हमें दिए गए पथ से एक पूर्ण URL को पुनर्निर्मित करने की अनुमति मिलती है।
अब जब हमारे पास यह फंक्शन है, तो हम उस समस्या का ध्यान रख सकते हैं जो हमारे पास है यदि कोई पथ किसी परिभाषित रूट से मेल नहीं खाता। हम `updateRoute` फंक्शन को संशोधित करेंगे और यदि हम कोई मेल नहीं पाते हैं तो मौजूदा रूट्स में से एक पर फॉलबैक जोड़ेंगे।
```js
function updateRoute() {
const path = window.location.pathname;
const route = routes[path];
if (!route) {
return navigate('/login');
}
...
```
यदि कोई रूट नहीं मिल सकता है, तो अब हम `login` पेज पर रीडायरेक्ट करेंगे।
अब एक फंक्शन बनाएं जो लिंक पर क्लिक किए जाने पर URL प्राप्त करे और ब्राउज़र के डिफ़ॉल्ट लिंक व्यवहार को रोके:
```js
function onLinkClick(event) {
event.preventDefault();
navigate(event.target.href);
}
```
आइए हमारे *लॉगिन* और *लॉगआउट* लिंक में HTML में बाइंडिंग जोड़कर नेविगेशन सिस्टम को पूरा करें।
```html
Login
...
Logout
```
ऊपर `event` ऑब्जेक्ट क्लिक इवेंट को कैप्चर करता है और इसे हमारे `onLinkClick` फंक्शन में पास करता है।
[`onclick`](https://developer.mozilla.org/docs/Web/API/GlobalEventHandlers/onclick) एट्रिब्यूट का उपयोग करके क्लिक इवेंट को जावास्क्रिप्ट कोड से बाइंड करें, यहां `navigate()` फंक्शन को कॉल करें।
इन लिंक पर क्लिक करके देखें, अब आपको अपने ऐप की विभिन्न स्क्रीन के बीच नेविगेट करने में सक्षम होना चाहिए।
✅ `history.pushState` मेथड HTML5 मानक का हिस्सा है और [सभी आधुनिक ब्राउज़रों](https://caniuse.com/?search=pushState) में लागू किया गया है। यदि आप पुराने ब्राउज़रों के लिए वेब ऐप बना रहे हैं, तो इस API के स्थान पर एक ट्रिक का उपयोग किया जा सकता है: पथ से पहले [हैश (`#`)](https://en.wikipedia.org/wiki/URI_fragment) का उपयोग करके आप रूटिंग को लागू कर सकते हैं जो नियमित एंकर नेविगेशन के साथ काम करता है और पेज को रीलोड नहीं करता है, क्योंकि इसका उद्देश्य पेज के भीतर आंतरिक लिंक बनाना था।
## ब्राउज़र के बैक और फॉरवर्ड बटन को संभालना
`history.pushState` का उपयोग ब्राउज़र के नेविगेशन हिस्ट्री में नए एंट्री बनाता है। आप इसे ब्राउज़र के *बैक बटन* को दबाकर देख सकते हैं, यह कुछ इस तरह दिखाना चाहिए:

यदि आप बैक बटन पर कुछ बार क्लिक करते हैं, तो आप देखेंगे कि वर्तमान URL बदलता है और हिस्ट्री अपडेट होती है, लेकिन वही टेम्पलेट प्रदर्शित होता रहता है।
ऐसा इसलिए है क्योंकि एप्लिकेशन को यह नहीं पता कि हमें हर बार हिस्ट्री बदलने पर `updateRoute()` को कॉल करने की आवश्यकता है। यदि आप [`history.pushState`](https://developer.mozilla.org/docs/Web/API/History/pushState) के दस्तावेज़ को देखते हैं, तो आप देख सकते हैं कि यदि स्टेट बदलता है - यानी हम एक अलग URL पर चले गए - तो [`popstate`](https://developer.mozilla.org/docs/Web/API/Window/popstate_event) इवेंट ट्रिगर होता है। हम इस समस्या को ठीक करने के लिए इसका उपयोग करेंगे।
### कार्य
यह सुनिश्चित करने के लिए कि ब्राउज़र हिस्ट्री बदलने पर प्रदर्शित टेम्पलेट अपडेट हो, हम एक नया फंक्शन अटैच करेंगे जो `updateRoute()` को कॉल करता है। हम इसे अपने `app.js` फ़ाइल के नीचे करेंगे:
```js
window.onpopstate = () => updateRoute();
updateRoute();
```
> नोट: हमने यहां अपने `popstate` इवेंट हैंडलर को संक्षिप्तता के लिए [एरो फंक्शन](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Functions/Arrow_functions) का उपयोग करके घोषित किया, लेकिन एक नियमित फंक्शन भी समान रूप से काम करेगा।
एरो फंक्शन पर एक रिफ्रेशर वीडियो यहां है:
[](https://youtube.com/watch?v=OP6eEbOj2sc "एरो फंक्शन")
> 🎥 ऊपर दी गई छवि पर क्लिक करें एरो फंक्शन के बारे में वीडियो देखने के लिए।
अब अपने ब्राउज़र के बैक और फॉरवर्ड बटन का उपयोग करने का प्रयास करें, और जांचें कि इस बार प्रदर्शित रूट सही ढंग से अपडेट हो रहा है।
---
## 🚀 चुनौती
इस ऐप के लिए क्रेडिट्स दिखाने वाले तीसरे पेज के लिए एक नया टेम्पलेट और रूट जोड़ें।
## पोस्ट-लेक्चर क्विज़
[पोस्ट-लेक्चर क्विज़](https://ff-quizzes.netlify.app/web/quiz/42)
## समीक्षा और स्व-अध्ययन
रूटिंग वेब विकास के आश्चर्यजनक रूप से कठिन हिस्सों में से एक है, खासकर जब वेब पेज रिफ्रेश व्यवहार से सिंगल पेज एप्लिकेशन पेज रिफ्रेश में स्थानांतरित होता है। [Azure Static Web App सेवा](https://docs.microsoft.com/azure/static-web-apps/routes/?WT.mc_id=academic-77807-sagibbon) रूटिंग को कैसे संभालती है, इसके बारे में थोड़ा पढ़ें। क्या आप समझा सकते हैं कि उस दस्तावेज़ में वर्णित कुछ निर्णय क्यों आवश्यक हैं?
## असाइनमेंट
[रूटिंग में सुधार करें](assignment.md)
---
**अस्वीकरण**:
यह दस्तावेज़ AI अनुवाद सेवा [Co-op Translator](https://github.com/Azure/co-op-translator) का उपयोग करके अनुवादित किया गया है। जबकि हम सटीकता सुनिश्चित करने का प्रयास करते हैं, कृपया ध्यान दें कि स्वचालित अनुवाद में त्रुटियां या अशुद्धियां हो सकती हैं। मूल दस्तावेज़, जो इसकी मूल भाषा में है, को प्रामाणिक स्रोत माना जाना चाहिए। महत्वपूर्ण जानकारी के लिए, पेशेवर मानव अनुवाद की सिफारिश की जाती है। इस अनुवाद के उपयोग से उत्पन्न किसी भी गलतफहमी या गलत व्याख्या के लिए हम उत्तरदायी नहीं हैं।