نمایش نتایج
محتوای اصلی صفحه لیستی از وعده های غذایی است که در جستجوی موفقیت آمیز نمایش داده می شود. ما می توانیم یک پیام نگهدارنده در حال حاضر اضافه کنیم که در یک حاوی پیچیده شده است div
عنصر با شناسه search-results
. ما به صورت پویا از جاوا اسکریپت برای افزودن عناصر به صفحه در این ظرف استفاده خواهیم کرد.
<div id="search-results" class="container padding-tb-30px"> Search for a meal... </div>
جاوا اسکریپت
من یک را می گیرم رویکرد کلاس محور برای شروع کار با منطق جاوا اسکریپت. هدف این جهت این است که کل کلاس جاوا اسکریپت را به یک نمونه قابل استفاده مجدد تبدیل کند که در صورت لزوم در صفحات مختلف مورد استفاده قرار گیرد.
من در مورد چگونگی وارد جزئیات نمی شوم کلاس ها در جاوا اسکریپت کار می کند، اما ایده اصلی این است که به الگوهای برنامه نویسی شی گرا مربوط می شود. زبان هایی مانند روبی، PHPو بیشتر از این اصول اغلب استفاده کنید.
بیایید ابتدا یک کلاس جدید ایجاد کنیم Search
.
class Search { constructor() {} }
کلاس می تواند آرگومان هایی را بپذیرد که در نهایت ویژگی های قابلیت استفاده مجدد را که قبلاً ذکر کردم به آن می دهد.
من نمونه ای از عنصر فرم را در نشانه گذاری HTML ایجاد می کنم.
قبل از انجام این کار، من به آن گوش خواهم داد DOMContentLoaded رویداد، به این معنی که صفحه HTML باید قبل از اجرای هر کدی در داخل بدنه تابع، ابتدا بارگذاری شود.
class Search { constructor(form) { this.form = form this.results = document.querySelector("#search-results") } initialize() { console.log(this.form) } } // Listen for the DOM Content load document.addEventListener("DOMContentLoaded", () => { // Query for the `search-form` const form = document.querySelector("#search-form") // Create a new instance of our Search class and pass the instance of the form through const search = new Search(form) // call the initialize function search.initialize() })
توجه کنید که چگونه Search
کلاس خارج از document.addEventListener
عملکرد. من این تصمیم را عمداً گرفتم زیرا به لطف دامنه جهانی می توانیم از داخل تابع دیگر به کلاس ارجاع دهیم.
این initialize
تابعی است که من برای به کار بردن منطق خود ایجاد کردم. به طور معمول، شما باید یک نمونه کلاس جدید را به یک متغیر اختصاص دهید و تنها پس از آن متدها را روی آن فراخوانی کنید.
تابع سازنده یک آرگومان را تشکیل میدهد و به ما اجازه میدهد آن را به یک نمونه جدید در the اختصاص دهیم Search
کلاس این پیکربندی به ما یک راه سطح بالا برای دسترسی مداوم به فرم می دهد.
من یک نمونه دیگر به آن اضافه کردم search-results
div را چند قدم به عقب در HTML اضافه کردیم. باز هم این به ما یک مرجع آسان به نتایج می دهد زیرا به آن نیاز داریم.
در مثال کد بالا، خروجی از initialize()
تابع باید عنصر فرم را در لاگ کنسول مرورگر شما برگرداند.
جستجو در ارسال فرم
برای انجام یک جستجو به رویداد ارسال فرم گوش میدهیم که به روش شنونده رویدادی که قبلاً استفاده میکردیم نیاز دارد. در داخل تابع مقداردهی اولیه، من منطق جستجو را به یک تابع جدید در داخل استخراج می کنم Search
کلاس ابتدا می توانیم بررسی کنیم که آیا فرم وجود دارد یا خیر و اگر وجود ندارد، false را برگردانیم. اگر فرم وجود نداشت، به این دلیل بود که جاوا اسکریپت را در صفحه دیگری بارگیری کردید که عنصری با ایده نداشت. search-form
حاضر.
class Search { constructor(form) { this.form = form this.results = document.querySelector("#search-results") } initialize() { // Don't initialize if the form isn't present if (this.form == null) { return } this.search() } }
تابع جستجوی جدید در داخل Search
کلاس و بیشتر منطق مورد نیاز ما را مدیریت می کند.
class Search { //... search() { const searchField = this.form.querySelector("input[type=text]") if (searchField) { this.form.addEventListener("submit", () => { // Fetch API for results, if any }) } } }
در داخل تابع، ابتدا فیلد ورودی را که در آن کاربر عبارت جستجوی خود را وارد می کند، جستجو می کنیم.
ما بررسی می کنیم که آیا فیلد با یک ساده وجود دارد یا خیر if
بیانیه و سپس پردازش برای گوش دادن به فرم ها submit
رویداد.
در داخل بدنه تابع رویداد ارسال، از داخلی استفاده می کنیم واکشی API برای رسیدگی به درخواست های AJAX به MealDB API.
const API_URL = " const SEARCH_BY_NAME = "search.php?" class Search { //... search() { const searchField = this.form.querySelector("input[type=text]") if (searchField) { this.form.addEventListener("submit", () => { return fetch( `${API_URL + SEARCH_BY_NAME}` + new URLSearchParams({ s: searchField.value.replace(/\s+/g, ""), }), { method: "GET", } ) .then((response) => { response.json().then((data) => { if (data.meals) { this.displaySearchResults(data.meals) } else { this.results.innerHTML = "No results" } }) }) .catch((error) => { console.log("error", error) }) }) } } }
اینجا چه اتفاقی دارد میافتد؟
یک سری در اینجا اتفاق می افتد، بنابراین سعی می کنم همه چیز را باز کنم.
ابتدا URL API خود را تنظیم می کنیم و آن را به یک متغیر ثابت به نام اختصاص می دهیم API_URL
. از آنجایی که MealDB API برای استفاده آموزشی رایگان است، یک کلید API از 1
در حال حاضر در داخل URL است. استفاده از یک API خصوصی یا چیز پیچیدهتر ممکن است به مراحل بیشتری برای بهینهسازی این کار نیاز داشته باشد.
من یک متغیر دیگر برای ثابت اضافه کردم SEARCH_BY_NAME
زیرا API به شما امکان می دهد سبک های مختلف جستجو را انجام دهید. در این آموزش، تمرکز ما بر روی نام وعده های غذایی است.
داخل بدنه submit
تابع addEventListener، من یک درخواست واکشی را به یک URL پویا که با متغیرهایی که در بالای فایل ساختهایم ساخته شده است، برمیگردانم. انتهای URL نمونه جدیدی از آن را می گیرد URLSearchParams
رابط.
این رابط پرس و جوی ما را به گونه ای قالب بندی می کند که API به طور خودکار آن را بپذیرد، که یک صرفه جویی در زمان است. در داخل نمونه URLSearchParams، میتوانیم یک شی را ارسال کنیم که حاوی یک جفت کلید-مقدار است. کلید (s
) چیزی است که MealDB API انتظار دارد. ارزش (searchField.value.replace(/\s+/g,)
) مقدار ورودی جستجوی متن کلیدهای کاربر است.
این replace
در صورتی که رشته حاوی فضای خالی باشد، می بینید که تمام فضای سفید را حذف می کند.
Fetch API به شما امکان می دهد نوع درخواست HTTP را تنظیم کنید. ما میخواهیم دادهها را «دریافت» کنیم، بنابراین من «GET» را بهعنوان علامت انتخاب کردم روش گزینه.
وعده ها، وعده ها
برگرداندن داده از یک درخواست واکشی شامل چیزی است که به نام شناخته می شود وعده ها در جاوا اسکریپت Promise راهی برای بررسی وضعیت درخواست HTTP و اجرای منطق بر اساس آن وضعیت است.
اگر وعده “تحقق شد” از a استفاده می کنیم then()
روشی برای رسیدگی به پاسخ و انجام کاری با داده ها. پاسخی که برمی گردد اغلب است JSON
داده ها، بنابراین ما آن را برمی گردانیم response.json()
داده و دیگری انجام دهید then()
تابعی که در نهایت به داده های واقعی دسترسی داریم.
در این مثال، ما تمام وعدههای غذایی را که با درخواست کاربر مطابقت دارند در فرم جستجو برمیگردانیم. اگر وعدههای غذایی وجود داشته باشد، تابعی را که در پایینتر کلاس ایجاد کردهام فراخوانی میکنیم this.displaySearchResults(data.meals)
و داده ها را برای استفاده در آنجا ارسال کنید.
در این مثال، this
کلمه کلیدی به والد اشاره دارد Search
کلاس
اگر هیچ نتیجه ای وجود نداشت، می توانیم به روز رسانی کنیم div#search-results
ظرفی با یک رشته متن که به کاربر نهایی می گوید چه اتفاقی افتاده است.
در نهایت، اگر خطایی در درخواست واکشی وجود داشته باشد، میتوانیم به آن برگردیم catch()
روش و خطا را به هر شکلی که ترجیح می دهیم نمایش دهیم.
نمایش نتایج
بیایید برخی از نتایج را در داخل نمایش دهیم displaySearchResults
عملکردی که قبلا ذکر کردم درون Search
کلاس، موارد زیر را اضافه کنید:
class Search { //... code omitted for brevity displaySearchResults(meals) { this.results.innerHTML = "" meals.forEach((meal) => { const template = `<div class="margin-bottom-30px"> <div class="background-white thum-hover box-shadow hvr-float full-width"> <div class="float-md-left margin-30px thum-xs"> <img class="width-150px search-item-photo" src=" alt=""> </div> <div class="padding-25px"> <div class="rating"> <ul> <li class="active"></li> <li class="active"></li> <li class="active"></li> <li class="active"></li> <li></li> </ul> </div> <h3><a href="${meal.strSource}" class="d-block text-dark text-capitalize text-medium margin-tb-15px search-item-title">${meal.strMeal}</a></h3> <hr> <div class="row no-gutters"> <div class="col-4 text-left"><a href="#" class="text-red"><i class="far fa-heart"></i> Save</a></div> <div class="col-8 text-right"><a href="#" class="text-grey-2"><i class="fas fa-map"></i> ${meal.strArea}</a> </div> </div> </div> <div class="clearfix"></div> </div> </div>` this.results.insertAdjacentHTML("beforeend", template) }) } }
اگر به خاطر دارید، در داخل search()
تابع را نامیدیم displaySearchResults()
تابع و در داده های درخواست API ارسال می شود. این دادهها آرایهای از وعدههای غذایی است که ممکن است در MealDB API براساس عبارت جستجوی کاربر نهایی وجود داشته باشد. اگر داده ها برمی گردند، می خواهیم محتوای صفحه جستجو را با لیستی از آن نتایج به روز کنیم.
این displaySearchResults()
تابع ابتدا محتوای HTML موجود در بخش نتایج جستجو را خالی می کند.
forEach()
روش. این روش به شما اجازه می دهد تا روی هر نتیجه حلقه بزنید و منطق را انجام دهید.در مورد ما، من از طریق هر وعده غذایی که از API برمیگردد حلقه زدم و سپس محتوای آن را به یک الگوی سفارشی اختصاص دادم. ما استفاده می کنیم قالب جاوا اسکریپت و درون یابی رشته ای نقشه برداری داده ها به روشی بسیار ساده تر از نسخه های قبلی جاوا اسکریپت.
من از ساده استفاده کردم console.log
بیانیه در forEach
حلقه بزنید تا بدانید چه چیزی برای استفاده در قالب موجود است.
در نهایت، در هر تکرار از forEach
حلقه، من از یک روش دستی به نام استفاده کردم insertAdjacentHTML
، که به شما این امکان را می دهد که این کار را انجام دهید. HTML را می توان به روش های مختلفی درج کرد، بنابراین این را بررسی کنید مشخصات بر روی آن.
از آنجا که ما در حال ساخت یک لیست هستیم، می خواهم هر نتیجه جدید را به کل لیست اضافه کنم، بنابراین موقعیت beforeend
بیشترین حس را دارد
اکنون سعی کنید غذای مورد علاقه خود را جستجو کنید و ببینید آیا هیچ وعده غذایی در لیست نتایج بازمی گردد یا خیر.
با هر موفقیتی، ما شاهد برخی از وعده های غذایی هستیم!
افکار بسته
این آموزش به شما آموزش می دهد که چگونه جاوا اسکریپت و یک API را ترکیب کنید تا یک ابزار جستجوی غنی و الهام بخش برای برخی از وعده های غذایی خوشمزه بسازید. از اینجا، من توصیه میکنم معیارهای جستجو را به دستهها و هر چیز دیگری که MealDB API ارائه میدهد گسترش دهید. کد نویسی مبارک!
بیشتر آموزش های جاوا اسکریپت مبتنی بر API
این آموزش های مبتنی بر پروژه را بررسی کنید تا به شما در یادگیری نحوه عملکرد API ها کمک کند.