ساخت اپلیکیشن ToDo با مجموعه MEVN (بخش دوم) – از صفر تا صد


در بخش قبلی این راهنما اقدام به راهاندازی پروژه ToDo با مجموعه MEVN کردیم که شامل مراحل کلاینت Vue، بکاند Node/Express و Axios برای ارتباط بین کلاینت و سرور بود. برای مشاهده این مطلب میتوانید به لینک زیر مراجعه کنید:
اینک طرح کلی پروژه ایجاد شده و قصد داریم اقدام به پیادهسازی پایگاه داده MongoDB در مجموعه MEVN بکنیم.
ایجاد MongoDB روی MongoAtlas
MongoDB یک سرویس پایگاه داده ساده ابری به نام MongoAtlas را اجرا میکند. استفاده از آن کار سادهای است، دارای طرح رایگان است و بسیار بهتر از میزبانی کل یک پایگاه داده به صورت محلی است. بنابراین اولین کاری که باید بکنیم ایجاد یک حساب کاربری در این صفحه (+) است.
با پیگیری دستورالعملهای نصب برای دریافت یک طرح رایگان و انتخاب کردن ارائهدهندهای که دارای طرح رایگان است به انتخاب کلاستر M0 میرسیم که کاربرد رایگان دائمی دارد. زمانی که این طرح را انتخاب کردیم باید نخستین کاربر را روی کلاستر بسازیم. در ادامه به برگه «Security» میرویم و با کلیک روی «Add New User» یک کاربر با تنظیمات زیر ایجاد میکنیم:
سپس باید IP خودتان را جهت دسترسی در «لیست سفید» (whitelist) قرار دهید. Atlas بخش عمده کار را برای شما انجام میدهد. با این حال همچنان باید به برگه Security رفته و با مراجعه به بخش IP Whitelist روی دکمه Add IP Address کلیک کنید. در پنجرهای که باز میشود روی گزینه Allow Access From Anywhere کلیک کرده و آن را تأیید کنید. زمانی که با این برنامه آشنا شدید، میتوانید تنظیمات سفارشی در خصوص قرار دادن IP در لیست سفید داشته باشید.
در نهایت زمان آن فرا میرسد که به کلاستر خود متصل شوید. در نوار جانبی سمت چپ روی «Clusters» کلیک کنید. بدین ترتیب داشبورد کلاستر پدیدار میشود. در این صفحه روی Connect کلیک کنید.
در پنجره باز شده گزینه Connect Your Application را به عنوان روش اتصال انتخاب کنید. در پنجره دیگر گزینه Short SRV connection string را انتخاب کرده و آدرس SRV را کپی کنید. در گام بعدی به این مقدار نیاز خواهید داشت، لذا آن را در جای مطمئنی ذخیره کنید.
اتصال به سرور با استفاده از MongoDB
اینک که تنظیمات پایگاه داده Mongo Atlas به انجام رسیده است، میتوانیم آن را به سرور خود اضافه کنیم. ابتدا باید بسته npm مربوط به mongodb را روی پوشه سرور نصب کنیم و سپس به پوشه سرور رفته و دستور زیر را اجرا کنیم:
npm install —-save mongodb
سپس در مسیر server/src/app.js باید mongodb را ایمپورت کرده، اتصال را برپا کنیم و در نهایت در عمل متصل شویم. همه این کارها با کد زیر صورت میگیرند:
1const mongo = require('mongodb')
2const MongoClient = mongo.MongoClient
3const uri = YOUR_CONNECTION_STRING
4var client;
5var mongoClient = new MongoClient(uri, { reconnectTries :
6Number.MAX_VALUE, autoReconnect : true, useNewUrlParser : true })
7mongoClient.connect((err, db) => { // returns db connection
8 if (err != null) {
9 console.log(err)
10 return
11 }
12 client = db
13})
اینک که اتصالی به کلاستر خود ساختهایم، نوبت آن است که به صورت عملی شروع به خواندن و نوشتن در یک «کلکسیون» (collection) بکنیم.
ایجاد یک کلکسیون
اگر به Mongo Atlas بازگردیم، میتوانیم نخستین کلکسیون خود را ایجاد کنیم. در برگه Cluster’s Overview روی دکمه Collections کلیک کنید. در این بخش روی دکمه Create Database کلیک کنید. برای سهولت کار نام پایگاه داده را test و نام کلکسیون را todos انتخاب میکنیم.
نکته: اگر نام پایگاه داده خود را چیزی به جز test قرار میدهید، باید رشته اتصالی که در ادامه میآید را به همین ترتیب تغییر دهید. در این حالت کافی است واژه test را در رشته uri به نام پایگاه دادهای که انتخاب کردهاید تغییر دهید.
اینک در پایگاه داده todos خود روی گزینه Insert Document کلیک کنید و نخستین سند را با فیلد title که نشاندهنده یک todo است وارد نمایید.
دسترسی به گره Collection
اینک به فایل app.js خودمان بازمیگردیم و این سند را بارگذاری میکنیم. از آنجا که پایگاه داده را راهاندازی کردهایم، میتوانیم todo-ها را به جای «کدنویسی سخت» (Hardcoding) که قبلاً مشاهده کردید، از پایگاه داده دانلود کنیم. کد زیر از اتصال پایگاه دادهای که ایجاد کردیم برای کوئری زدن به کلکسیون todo-ها و بازگشت نتایج استفاده میکند.
1app.get('/todo', (req, res) => {
2 const collection = client.db("test").collection("todos")
3 collection.find().toArray(function (err, results) {
4 if (err) {
5 console.log(err)
6 res.send([])
7 return
8 }
9
10 res.send(results)
11 })
12})
اکنون در آدرس http://localhost:8080/#/todo باید ببینیم که کلکسیون ما در لیست مربوطه به صورت زیر رندر میشود:
نوشتن در پایگاه داده
این بخش چندین جزء متفاوت دارد. ابتدا باید کامپوننت ورودی را به کد HTML خود اضافه کنیم. سپس باید از axios برای ارسال ورودی به فایل app.js روی سرور استفاده کرده و در نهایت با بهرهگیری از بسته mongodb دادهها را روی پایگاه داده بنویسیم.
در این مرحله، ابتدا باید فایل ToDo.vue را طوری ویرایش کنیم که شامل فرم شود و ورودی آن را به ToDoAPI خود بفرستیم. لذا در فایل ToDo.vue تغییرات زیر را اعمال میکنیم:
1<template lang="html">
2 <div>
3 <form v-on:submit='addTodo($event)'>
4 <input type='text' placeholder='Enter Todo' v-model='newTodo'/>
5 <input type='submit' />
6 </form>
7 <ul>
8 <li v-for='todo in todos' :key='todo._id'>
9 <span>{{todo}}</span>
10 </li>
11 </ul>
12 </div>
13</template>
14
15<script>
16import ToDoAPI from '@/services/ToDoAPI.js'
17export default {
18 data () {
19 return {
20 newTodo: '',
21 todos: []
22 }
23 },
24 mounted () {
25 this.loadTodos()
26 },
27 methods: {
28 async addTodo (evt) {
29 evt.preventDefault() // prevents the form's default action from redirecting the page
30 const response = await ToDoAPI.addTodo(this.newTodo)
31 this.todos.push(response.data)
32 this.newTodo = '' // clear the input field
33 },
34 async loadTodos () {
35 const response = await ToDoAPI.getToDos()
36 this.todos = response.data
37 }
38 }
39}
40</script>
41
42<style lang="css">
43</style>
پس از افزودن ورودی به html قالب که به متغیر داده متصل شده است، از مدیریت رویداد Vue برای اتصال رویداد submit به تابع addTodo خود استفاده میکنیم. سپس بار دیگر از axios برای فراخوانی یک push بهره میگیریم که در ادامه تعریف خواهیم کرد. سپس پاسخ را به لیست todo خودمان اضافه میکنیم و ورودی را پاک میکنیم تا کاربر بتواند به سادگی todo-های دیگری را اضافه کند.
اینک باید تابع (addTodo(todo را در فایل services/ToDoAPI.js اضافه کنیم. به این منظور کافی است فیلد زیر را اضافه کنیم.
1addTodo (todo) {
2 return API().push('addTodo', {
3 todo: todo // add our data to the request body
4 })
5}
پس در عمل باید مسیر سمت سرور را تعریف کنیم. این کار را در فایل server/src/app.js انجام میدهیم:
1app.post('/addTodo', (req, res) => {
2 const collection = client.db('test').collection('todos')
3 var todo = req.body.todo // parse the data from the request's body
4 collection.insertOne({title: todo}, function (err, results) {
5 if (err) {
6 console.log(err)
7 res.send('')
8 return
9 }
10 res.send(results.ops[0]) // returns the new document
11 })
12})
بدین ترتیب زمانی که فرم را تحویل میدهیم، باید ببینیم که لیست todo-ی ما با توجه به ورودیمان بهروزرسانی میشود. ضمناً اگر پایگاه داده Mongo Atlas خود را بررسی کنیم، خواهیم دید که دادهها به پایگاه داده اضافه شدهاند.
بررسی کردن ToDo-ها
تا به این جا بخشهای زیادی از اپلیکیشن خود را راهاندازی کردهایم. ما اکنون میتوانیم todo-ها را با استفاده از MongoDB به لیست خود اضافه کنیم؛ اما یک فهرست از Todo بدون امکان بررسی و فهرست کردن آنها و همچنین امکان حذف کردن موارد غیرضروری از پایگاه داده به درد نمیخورد.
این فرایند اساساً متضاد روش افزودن Todo است. ما هر آیتم لیست را به یک ورودی checkbox اضافه میکنیم و زمانی که تیک آنها برداشته شود از axios و node بهره میگیریم تا آن عنصر را از لیست حذف کنیم. تنها تفاوت این است که باید از ObjectID سند برای حذف آن استفاده کنیم. این رویه خوبی است، زیرا معمولاً میبینیم که todo-های تکراری با عنوان مشابه وجود دارند و از این رو حذف کردن آنها بر حسب عنوان ممکن است موجب حذف عنصر نادرستی شود.
در فایل Todo.vue باید تگهای span را که Todo-ها را فهرست میکنند به ورودیهای از نوع checkbox تغییر دهیم که وقتی کلیک میشوند یک متد را فراخوانی میکنند.
1<li v-for='todo in todos' :key='todo._id'>
2 <input type='checkbox' @click='deleteTodo(todo._id)'> {{todo.title}}
3</li>
سپس باید متد deleteTodo را تعریف کنیم که مورد انتخابی را از لیست todo های رندر شده حذف میکند و از axios برای ارسال درخواست به سرور استفاده میکند.
1deleteTodo (todoID) {
2 ToDoAPI.deleteTodo(todoID)
3 // remove the array element with the matching id
4 this.todos = this.todos.filter(function (obj) {
5 return obj._id !== todoID
6 })
7}
یک بار دیگر فایل services/ToDoAPI.js را ویرایش میکنیم تا به مدیریت تابع deleteTodo پرداخته و سرور را فراخوانی کند.
1deleteTodo (todoID) {
2 return API().post('deleteTodo', {
3 todoID: todoID // add our data to the request body
4 })
5}
در نهایت فایل سرور خود را طوری ویرایش میکنیم که عنصر را عملاً از پایگاه داده حذف کند. یک نکته مهم که باید به خاطر سپرد این است که todoID به صورت یک رشته ارسال میشود و اگر بخواهیم از آن برای کوئری کردن به پایگاه داده استفاده کنیم، باید آن را به یک ObjectID تبدیل کنیم.
1app.post('/deleteTodo', (req, res) => {
2 const collection = client.db('test').collection('todos')
3 // remove document by its unique _id
4 collection.removeOne({'_id': mongo.ObjectID(req.body.todoID)}, function (err, results) {
5 if (err) {
6 console.log(err)
7 res.send('')
8 return
9 }
10 res.send() // return
11 })
12})
سخن پایانی
اینک ما یک اپلیکیشن لیست Todo کامل داریم که با استفاده از مجموعه MEVN کار میکند. همه دادهها در MongoDB ذخیره میشوند. مجموعه MEVN یک روش عالی ماژولار برای ساخت وب اپلیکیشنها محسوب میشود. با این که همه چیز به خوبی کار میکند؛ اما یک مرحله نهایی هم وجود دارد:
زیباسازی اپلیکیشن
هیچ کس تمایل ندارد که به کادرهای ورودی ساده نگاه کند، طراحی فرانتاند میتواند تفاوت زیادی در یک اپلیکیشن ایجاد کند. ما قصد نداریم زمان زیادی را صرف توضیح آن چه میخواهیم انجام دهیم بکنیم. شما احتمالاً با روش استفاده از CSS آشنا هستید، بنابراین صرفاً محصول نهایی را که با استفاده از CSS ساختهایم نمایش میدهیم.
برای بررسی کامل این اپلیکیشن نهایی به این ریپوی گیتهاب (+) مراجعه کنید. اینک شما با مبانی راهاندازی یک مجموعه MEVN آشنا هستید و میتوانید به جلو حرکت کرده و آن چه در ذهن خود دارید را ایجاد کنید.
اگر این مطلب برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای برنامهنویسی
- آموزش پیادهسازی یک پروژه وب کامل و ساده
- مجموعه آموزشهای طراحی و توسعه پروژههای وب
- آموزش راهاندازی و اجرای Express ،Node.js و MongoDB — راهنمای گام به گام
- پنج ابزار برای توسعه سریع اپلیکیشنهای Vue.js — راهنمای کاربردی
==