تا این قسمت از کار توانسته ایم درخواست خود را به API ارسال کرده و پاسخ دریافتی را در کنسول مرورگر نمایش دهیم. برای انجام این کار ابتدا کد مربوط به log کردن نتیجه در کنسول مرورگر را کامنت می کنیم تا دیگر نتیجه در این قسمت نمایش داده نشود. به جای آن می خواهم از کلاس ui متدی به نام paint را صدا بزنم که کار وارد کردن داده ها در UI را انجام دهد اما هنوز نه کلاس UI داریم و نه متدی به نام paint بنابراین به فایل Ui.js بروید تا کار را شروع کنیم.
من درون این فایل، کلاسی به نام UI تعریف می کنم که درون constructor خود، خصوصیت های بسیار زیادی را تعریف می کند چرا که ما عناصر بسیار زیادی را در گزارش های آب و هوایی داریم:
class UI { constructor() { this.location = document.getElementById('w-location'); this.desc = document.getElementById('w-desc'); this.string = document.getElementById('w-string'); this.details = document.getElementById('w-details'); this.icon = document.getElementById('w-icon'); this.humidity = document.getElementById('w-humidity'); this.feelsLike = document.getElementById('w-feels-like'); this.dewpoint= document.getElementById('w-dewpoint'); this.wind = document.getElementById('w-wind'); } }
خصوصیات تعریف شده در کد بالا به ترتیب به شرح زیر هستند:
در مرحله بعد باید متدی در این کلاس تعریف کنیم که تمام این خصوصیات (که عناصر HTML هستند) را گرفته و اطلاعات مربوطه را در آن ها وارد کند. این متد، همان متد paint خواهد بود:
class UI { constructor() { this.location = document.getElementById('w-location'); this.desc = document.getElementById('w-desc'); this.string = document.getElementById('w-string'); this.details = document.getElementById('w-details'); this.icon = document.getElementById('w-icon'); this.humidity = document.getElementById('w-humidity'); this.feelsLike = document.getElementById('w-feels-like'); this.dewpoint= document.getElementById('w-dewpoint'); this.wind = document.getElementById('w-wind'); } paint(weather) { this.location.textContent = weather.display_location.full; this.desc.textContent = weather.weather; this.string.textContent = weather.temperature_string; this.icon.setAttribute('src', weather.icon_url); this.humidity.textContent = `Relative Humidity: ${weather.relative_humidity}`; this.feelsLike.textContent = `Feels Like: ${weather.feelslike_string}`; this.dewpoint.textContent = `DewPoint: ${weather.dewpoint_string}`; this.wind.textContent = `Wind: ${weather.wind_string}`; } }
شاید با خودتان بگویید که چطور می دانی محل مورد نظر (شهر) از شیء display_location.full به دست می آید. پاسخ این سوال همان چیزی است که قبلا گفته ام، ساختار هر API خاص است و شما باید پاسخ دریافتی از API را بررسی کرده تا بدانید هر اطلاعاتی در کدام قسمت از پاسخ قرار دارد. مثلا من این کار را در جلسه قبل انجام دادم (پاسخ دریافتی در کنسول مرورگر بود و به سادگی بررسی می شد). تنها نکته جالب در کد بالا نحوه تعیین icon است. برای تعیین منبع (src) یک تصویر باید از setAttribute (از متدهای خود جاوا اسکریپت) استفاده کنیم تا خصوصیت src را برایش تعریف کنیم. برای مقادیر انتهایی نیز یک یا دو کلمه توضیح قرار داده ام و سپس مقدار را نمایش داده ام تا کاربر بداند هر عدد مربوط به چه چیزی است.
حالا به app.js رفته و به صورت زیر از کلاس UI استفاده می کنیم:
// Init weather object const weather = new Weather('Boston', 'MA'); // Init UI const ui = new UI(); // Get weather on DOM load document.addEventListener('DOMContentLoaded', getWeather); function getWeather(){ weather.getWeather() .then(results => { ui.paint(results); }) .catch(err => console.log(err)); }
این کار عملیات پیچیده ای ندارد و فقط یک نمونه سازی و سپس استفاده از handle آن برای صدا زدن متد paint است.
مرحله بعد مدیریت modal است. از آنجایی که بوت استرپ از جی کوئری استفاده می کند ما برای بستن modal باید از جی کوئری استفاده کنیم. به فایل app.js بروید و event-listener زیر را به آن اضافه کنید:
// Get weather on DOM load document.addEventListener('DOMContentLoaded', getWeather); // Change location event document.getElementById('w-change-btn').addEventListener('click', (e) => { const city = document.getElementById('city').value; const state = document.getElementById('state').value; // Change location weather.changeLocation(city, state); // Get and display weather getWeather(); // Close modal $('#locModal').modal('hide'); });
دکمه ای که id اش برابر با w-change-btn است همان دکمه ذخیره شهر جدید در modal ما است (دکمه Save Changes). درون این event-listener مقادیر شهر و ایالت که توسط کاربر وارد می شوند را ذخیره کرده ایم تا با استفاده از متد Change Location محل را تغییر دهیم. سپس getWeather را صدا می زنیم تا اطلاعات محل جدید را از API بگیریم و سپس با یک دستور ساده جی کوئری modal را می بندیم. اگر دوست ندارید از جی کوئری استفاده کنید می توانید از جاوا اسکریپت ساده برای بستن modal استفاده نمایید. می توانید این کد را در مرورگر خود تست کنید.
در مرحله بعد وارد فایل Storage.js می شویم تا یک کلاس مخصوص local storage ایجاد کنیم. چرا؟ به دلیل اینکه اگر کاربر شهر مورد نظرش را از بوستون (حالت پیش فرض) به شهر دیگری تغییر داده و سپس صفحه را refresh کند، دوباره اطلاعات بوستون نمایش داده می شود. ما می خواهیم شهر کاربر را درون local storage ذخیره کنیم تا با refresh شدن صفحه شهر کاربر تغییر نکند:
class Storage { constructor() { this.city; this.state; this.defaultCity = 'Tampa'; this.defaultState = 'FL'; } getLocationData() { if(localStorage.getItem('city') === null) { this.city = this.defaultCity; } else { this.city = localStorage.getItem('city'); } if(localStorage.getItem('state') === null) { this.state = this.defaultState; } else { this.state = localStorage.getItem('state'); } return { city: this.city, state: this.state } } setLocationData(city, state) { localStorage.setItem('city', city); localStorage.setItem('state', state); } }
از آنجایی که چندین بار در طول این دوره آموزشی با local storage کار کرده ایم فکر نمی کنم نیاز به توضیح دوباره آن باشد (اگر سوالی دارید می توانید در بخش کامنت ها مطرح کنید). منطق کد ها نیز بسیار ساده است. من شهر پیش فرض را Tampa در ایالت فلوریدا انتخاب کرده ام. متد getLocationData از روی local storage مقادیر را می خواند و اگر چیزی در آن نبود از شهر پیش فرض استفاده می کند. در صورتی که شهری نیز ذخیره شده بود همان شهر را بر می گرداند. توجه کنید که در نهایت یک شیء حاوی city و state برگردانده ایم. متد setLocationData نیز شهر و ایالت را در local storage ثبت می کند.
حالا به فایل app.js برمی گردیم و در همان ابتدا local storage را می خوانیم (با نمونه سازی از کلاس Storage):
// Init storage const storage = new Storage(); // Get stored location data const weatherLocation = storage.getLocationData(); // Init weather object const weather = new Weather(weatherLocation.city, weatherLocation.state); // Init UI const ui = new UI();
همچنین همانطور که می بینید دیگر مقادیر را به صورت دستی (شهر بوستون) تنظیم نکرده ایم و همان مقدار موجود در local storage را به کلاس Weather پاس می دهیم. نهایتا باید هنگام کلیک روی دکمه save changes درون modal، شهر را نیز گرفته و در local storage ذخیره کنیم:
// Change location event document.getElementById('w-change-btn').addEventListener('click', (e) => { const city = document.getElementById('city').value; const state = document.getElementById('state').value; // Change location weather.changeLocation(city, state); // Set location in LS storage.setLocationData(city, state); // Get and display weather getWeather(); // Close modal $('#locModal').modal('hide'); });
به شما تبریک می گویم، پروژه خود را با موفقیت به اتمام رساندید. (دانلود سورس کد این پروژه)
در این قسمت، به پرسشهای تخصصی شما دربارهی محتوای مقاله پاسخ داده نمیشود. سوالات خود را اینجا بپرسید.