Arabic (العربية/عربي) translation by Rachid Sakara (you can also view the original English article)
في الجزء السابق من هذه السلسلة التعليمية، تعلمت كيفية العمل بوظيفة التعديل على تفاصيل المنشور لتدوينة معينة.
لكن في هذا الجزء، ستنفذ وظيفة حذف منشور مدونة موجود مسبقا كما ستقوم بتنفيذ وظيفة تسجيل خروج المستخدم.
لتبدأ
دعونا نبدأ بنسخ شفرة المصدر (source code) لأخر جزء من سلسلة البرنامج التعليمية.
1 |
git clone https://github.com/royagasthyan/AngularBlogApp-EditUpdate DeletePost |
إذهب إلى دليل المشروع الخاص بك ثم قم بتثبيت جميع الملحقات الضرورية .
1 |
cd DeletePost/client
|
2 |
npm install
|
3 |
cd DeletePost/server
|
4 |
npm install
|
بمجرد تثبيت الملحقات (dependencies) ، قم بإعادة تشغيل تطبيق العميل والخادم .
1 |
cd DeletePost/client
|
2 |
npm start |
3 |
cd DeletePost/server
|
4 |
node app.js |
توجه بمتصفحك إلى هذا العنوان http://localhost:4200 وسيكون لديك التطبيق شغال.
إضافة الموافقة على الحذف
لقد أضفت بالفعل رمز الحذف إلى المنشورات المدرجة في المدونة. عندما ينقر المستخدم على رمز الحذف الموافق لأي منشور مدونة ، تحتاج إلى إظهار تأكيد الحذف على شكل نافذة منبثقة. إذا قام المستخدم بالتأكيد على عملية الحذف فإنه يتوجب حذف منشور المدونة المعني بالأمر فقط .
دعونا نبدأ مع إضافة model نافدة التأكيد المنبثقة عند نقر المستخدم على زر الحذف. قم بإضافة التعليمات البرمجية لل model المنبثق التالي إلى ملف show-post.component.html
.
1 |
<div class="modal fade" id="deleteModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true"> |
2 |
<div class="modal-dialog" role="document"> |
3 |
<div class="modal-content"> |
4 |
<div class="modal-header"> |
5 |
<h5 class="modal-title" id="exampleModalLabel">Delete Post</h5> |
6 |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> |
7 |
<span aria-hidden="true">×</span> |
8 |
</button>
|
9 |
</div>
|
10 |
<div class="modal-body"> |
11 |
Are you sure ? |
12 |
</div>
|
13 |
<div class="modal-footer"> |
14 |
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> |
15 |
<button type="button" class="btn btn-primary">Delete</button> |
16 |
</div>
|
17 |
</div>
|
18 |
</div>
|
19 |
</div>
|
قم بالتعديل على رمز الحذف ليشمل خاصية data-target
كما هي ظاهرة :
1 |
<i data-toggle="modal" data-target="#deleteModal" title="Delete" class="fas fa-trash-alt" aria-hidden="true"></i> |
قم بحفظ التغييرات أعلاه وأعد تشغيل ال client server. سجيل الدخول إلى التطبيق وانقر على أيقونة الحذف المقابلة لأي منشور، وسينبثق لك modal نافذة التأكيد .



إنشاء API لحذف منشور مدونة
دعونا نقوم بإنشاء مسار REST API لحذف منشور مدونة . في ملف server/app.js
، أنشئ مسار REST API لتولي أمر حذف منشور مدونة إنطلاقا من id
الخاص بها . إليك كيف سيبدو مسار REST API .
1 |
app.post('/api/post/deletePost', (req, res) => { |
2 |
|
3 |
})
|
ابدأ من خلال الاتصال بقاعدة البيانات MongoDB باستخدام عميل Mongoose
.
1 |
mongoose.connect(url, { useMongoClient: true }, function(err){ |
2 |
// connection established
|
3 |
});
|
عليك الاستفادة من طريقة findByIdAndRemove
للعثور على منشور مدونة وحذفه باستخدام id
. حالما يتم حدفه بنجاح ، ستعيد status
إلى إستجابة . إليك كيف سيبدو مسار REST API :
1 |
app.post('/api/post/deletePost', (req, res) => { |
2 |
mongoose.connect(url, { useMongoClient: true }, function(err){ |
3 |
if(err) throw err; |
4 |
Post.findByIdAndRemove(req.body.id, |
5 |
(err, doc) => { |
6 |
if(err) throw err; |
7 |
return res.status(200).json({ |
8 |
status: 'success', |
9 |
data: doc |
10 |
})
|
11 |
})
|
12 |
});
|
13 |
})
|
المنادات على API الحدف
عندما ينقر المستخدم على رمز الحذف، يجب عليك الاحتفاظ بتفاصيل المنشور داخل متغير. إذا تابع المستخدم خيارالحذف بعد رسالة التأكيد ، سيتتوجب عليك المنادات على REST API الخاص بالحذف.
إضافة طريقة تسمى setDelete
إلى حدث النقر على زر الحذف show-post.component.html
. إليك كيف سيبدو:
1 |
<i (click)="setDelete(post)" data-toggle="modal" data-target="#deleteModal" title="Delete" class="fas fa-trash-alt" aria-hidden="true"></i> |
داخل ملف show-post.component.ts
، قم بتحديد متغير يسمى post_to_delete
.
قم بتحديد طريقة تسمى setDelete
داخل ملف show-post.component.ts
للحفاظ على إمكانية حذف تفاصيل المنشور .
1 |
setDelete(post: Post){ |
2 |
this.post_to_delete = post; |
3 |
}
|
عندما ينقر المستخدم على زر الإلغاء للنافذة المنبثقة . سيتوجب عليك النداء على الطريقة المسمات ب unsetDelete
لإعادة قيمة post_to_delete
إلى null . إليك كيف سيبدو الأمر :
1 |
unsetDelete(){ |
2 |
this.post_to_delete = null; |
3 |
}
|
إليك كيف سيبدو كود HTML الخاص بزر Cancel
لملف show-post.component.html
:
1 |
<button #closeBtn (click)="unsetDelete()" type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button> |
الأن دعنا نقوم بتحديد طريقة الخذمة (service method) المسمات deletePost
داخل ملف show-post.service.ts
. إليك كيف تبدو :
1 |
deletePost(id){ |
2 |
return this.http.post('/api/post/deletePost',{id : id}) |
3 |
}
|
للمنادات على الطريقة الخاصة بالخذمة من ShowPostComponent
، قم بتحديد طريقة تسمى deletePost
التي ستصف لنا طريقة deletePost
من ShowPostService
. إليك كيف ستبدو طريقة deletePost
على ShowPostComponent
.
1 |
deletePost(){ |
2 |
this.showPostService.deletePost(this.post_to_delete._id).subscribe(res => { |
3 |
this.getAllPost(); |
4 |
})
|
5 |
}
|
حالما يحذف المنشور ، سيكون عليك عمل refresh لقائمة المنشورات ، وبالتالي تحتاج إلى عمل نداء لطريقة getAllPost
. ستحتاج إيضا إلى إغلاق النافذة المنبتقة حالما تنتهي عملية الحذف بنجاح .
أولا ، قم بعمل import لمرجع ل ViewChild
و ElementRef
في ملف post.component.ts
.
1 |
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; |
قم بتحديد المتغير closeBtn
لإنشاء مرجع خاص بزر الإغلاق للنافذة المنبثقة.
1 |
@ViewChild('closeBtn') closeBtn: ElementRef; |
الأن ، غندما ثمت عملية نذاء الحذف (delete call) بنجاح ، تحتاج إلى إغلق نافذة تأكيد الحذف المنبثقة .
إليك كيف ستبدو طريقة deletePost
المعدلة.
1 |
deletePost(){ |
2 |
this.showPostService.deletePost(this.post_to_delete._id).subscribe(res => { |
3 |
this.getAllPost(); |
4 |
this.closeBtn.nativeElement.click(); |
5 |
})
|
6 |
}
|
إليك كيف سيبدو ملف show-post.component.ts
.
1 |
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core'; |
2 |
import { ShowPostService } from './show-post.service'; |
3 |
import { Post } from '../models/post.model'; |
4 |
import { CommonService, } from '../service/common.service'; |
5 |
|
6 |
@Component({ |
7 |
selector: 'app-show-post', |
8 |
templateUrl: './show-post.component.html', |
9 |
styleUrls: ['./show-post.component.css'], |
10 |
providers: [ ShowPostService ] |
11 |
})
|
12 |
export class ShowPostComponent implements OnInit { |
13 |
|
14 |
@ViewChild('closeBtn') closeBtn: ElementRef; |
15 |
|
16 |
public posts : any []; |
17 |
public post_to_delete; |
18 |
|
19 |
constructor(private showPostService: ShowPostService, private commonService: CommonService) { |
20 |
|
21 |
}
|
22 |
|
23 |
ngOnInit(){ |
24 |
this.getAllPost(); |
25 |
|
26 |
this.commonService.postAdded_Observable.subscribe(res => { |
27 |
this.getAllPost(); |
28 |
});
|
29 |
}
|
30 |
|
31 |
setDelete(post: Post){ |
32 |
this.post_to_delete = post; |
33 |
}
|
34 |
|
35 |
unsetDelete(){ |
36 |
this.post_to_delete = null; |
37 |
}
|
38 |
|
39 |
getAllPost(){ |
40 |
this.showPostService.getAllPost().subscribe(result => { |
41 |
console.log('result is ', result); |
42 |
this.posts = result['data']; |
43 |
});
|
44 |
}
|
45 |
|
46 |
editPost(post: Post){ |
47 |
this.commonService.setPostToEdit(post); |
48 |
}
|
49 |
|
50 |
deletePost(){ |
51 |
this.showPostService.deletePost(this.post_to_delete._id).subscribe(res => { |
52 |
this.getAllPost(); |
53 |
this.closeBtn.nativeElement.click(); |
54 |
})
|
55 |
}
|
56 |
|
57 |
}
|
قم بحفظ التغييرات أعلاه وأعد تشغيل ال client server. سجيل الدخول إلى التطبيق وانقر على أيقونة الحذف المقابلة لأي منشور. سينبثق لك صندوق التأكيد . وافق على حذق منشور المدونة . منشور المدونة سيحذف بينما سيتم تحديت قائمة المنشورات .
التعامل مع فترة تسجيل المستخدم (User Session) أثناء تسجيل الدخول
عندما يقوم المستخدم بتسجيل الدخول إلى التطبيق، عليك أن تبقي على إسم المستخدم الذي سجل الدخول في localstorage
.قمم بالتعديل على طريقة validateLogin
داخل LoginComponent
لتخزين اسم المستخدم الذي سجل الدخول في localstorage
.
عندما يتم المصادقة (validated) على نتيجة القادمة من نذاء API ، قم بإضافة التعليمات البرمجية التالية لتخزين اسم المستخدم الذي تم تسجيل الدخول به.
1 |
localStorage.setItem('loggedInUser', this.user.username); |
إليك كيف ستبدو طريقة validateLogin
.
1 |
validateLogin() { |
2 |
if(this.user.username && this.user.password) { |
3 |
this.loginService.validateLogin(this.user).subscribe(result => { |
4 |
if(result['status'] === 'success') { |
5 |
localStorage.setItem('loggedInUser', this.user.username); |
6 |
this.router.navigate(['/home']); |
7 |
} else { |
8 |
alert('Wrong username password'); |
9 |
}
|
10 |
}, error => { |
11 |
console.log('error is ', error); |
12 |
});
|
13 |
} else { |
14 |
alert('enter user name and password'); |
15 |
}
|
16 |
}
|
الأن، داخل ملف home.component.html
، قم بإضافة طريقة تسمى logout
لزر تسجيل الخروج .
1 |
<button (click)="logout()" type="button" class="btn btn-link"> |
2 |
Logout |
3 |
</button>
|
داخل ملف home.component.ts
، قمم بإنشاء طريقة تسمى logout
. داخل طريقة logout
، تحتاج إلى مسح التخزين المحلي من أجل loggedInUser
. إليك كيف ستبدو الطريقة :
1 |
logout(){ |
2 |
localStorage.removeItem('loggedInUser'); |
3 |
this.router.navigate(['/']); |
4 |
}
|
في طريقة constructor الخاصة ب HomeComponent
، تحتاج إلى إضافة تفقد لمفتاح loggedInUser
على مستوى التخزين المحلي . إذا لم يتم إيجاده ، فستحتاج إلى إعادة التوجيه إلى صفحة تسجيل الدخول . إليك كيف سيبدو ملف home.component.ts
.
1 |
import { Component, ViewChild, ElementRef } from '@angular/core'; |
2 |
import { CommonService } from '../service/common.service'; |
3 |
import { Router } from '@angular/router'; |
4 |
|
5 |
@Component({ |
6 |
selector: 'app-home', |
7 |
templateUrl: './home.component.html', |
8 |
styleUrls: ['./home.component.css'] |
9 |
})
|
10 |
export class HomeComponent { |
11 |
|
12 |
@ViewChild('addPost') addBtn: ElementRef; |
13 |
|
14 |
constructor(private commonService: CommonService, private router: Router){ |
15 |
|
16 |
if(!localStorage.getItem('loggedInUser')){ |
17 |
this.router.navigate(['/']); |
18 |
}
|
19 |
|
20 |
this.commonService.postEdit_Observable.subscribe(res => { |
21 |
this.addBtn.nativeElement.click(); |
22 |
});
|
23 |
|
24 |
}
|
25 |
|
26 |
logout(){ |
27 |
localStorage.removeItem('loggedInUser'); |
28 |
this.router.navigate(['/']); |
29 |
}
|
30 |
|
31 |
}
|
قم بحفظ التغييرات أعلاه وأعد تشغيل client server . حاول الولوج إلى الصفحة الرئيسية عن طريق وضعك لعنوان http://localhost:4200/home في نافذة المتصفح. بحيت سيتم إعادة توجيهك إلى صفحة تسجيل الدخول.
سجل الدخول إلى التطبيق وانقر على زر الخروج . سيتم تسجيل خروجك وإعادة توجيهك إلى صفحة تسجيل الدخول.
أمور يجب تغطيتها
في هذا الجزء من السلسلة التعليمية، تعلمت كيفية عمل حذف لمنشور من خلال إضافة رمز إلى قائمة منشورات المدونة . قمت أيضا بإنشاء REST API لحذف تفاصيل منشورمدونة من قاعدة البيانات MongoDB باستخدام عميل Mongoose
.
لقد قمت بالعمل فقط بالميزات الأساسية جدا من تطبيق التدويني ، ويمكن تطوير هذا التطبيق أكثر حتى يشمل العديد من الميزات.
كيف كانت تجربتك بتعلم إنشاء تطبيق التدوين باستخدام Angular MongoDB ؟ دعنا نعرف أفكارك واقتراحاتك في الجزء المخصص للتعليقات أدناه.
شفرة المصدر الخاصة بهذا الدرس تجدها على GitHub.
وأخيرا، تذكر أن JavaScript هي لغة الويب. وأنها ليست من دون منحنيات التعلم ، ولكن إذا كنت تبحث عن موارد إضافية للدراسة أو لاستخدامها في عملك، تفقد من ما لدينا متاح في Envato Market.