От автора: этот пост является частью серии статей «Создание приложения для блоггинга с использованием Angular и MongoDB». В предыдущей части этой серии вы узнали, как создать компонент для добавления в блог новых постов. Вы узнали, как создать конечную точку API REST для добавления новых постов в базу данных MongoDB. В этой части серии вы узнаете, как реализовать функционал для того, чтобы редактировать пост, существующий в блоге.
Приступим. Давайте начнем с клонирования исходного кода из последней части серии.
1 |
git clone //github.com/royagasthyan/AngularBlogApp-Post EditPost |
Перейдите в каталог проекта и установите необходимые зависимости.
1 2 3 4 |
cd EditPost/client npm install cd EditPost/server npm install |
После установки зависимостей перезапустите клиентское и серверное приложение.
1 2 3 4 |
cd EditPost/client npm start cd EditPost/server node app.js |
Откройте в браузере адрес //localhost:4200, и у вас должно запуститься приложение.
Реализация функционала редактирования поста
В ShowPostComponent мы добавим две иконки для редактирования и удаления поста. Мы будем использовать Font Awesome. Загрузите и включите папки Font Awesome в папке assets.
На странице src/app/index.html включите ссылку на CSS-стиль Font Awesome.
1 |
<link rel="stylesheet" type="text/css" href="./assets/fontawesome/web-fonts-with-css/css/fontawesome-all.min.css"> |
Теперь измените файл show-post/show-post.component.html, чтобы включить HTML-код для иконок редактирования и удаления.
1 2 3 4 |
<div> <i title="Edit" class="fas fa-edit" aria-hidden="true"></i> <i title="Delete" class="fas fa-trash-alt" aria-hidden="true"></i> </div> |
Вот как будет выглядеть выглядит файл show-post.component.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<div class="list-group"> <a *ngFor="let post of posts" class="list-group-item list-group-item-action flex-column align-items-start"> <div class="d-flex w-100 justify-content-between"> <h5 class="mb-1">{{post.title}}</h5> <small>3 days ago</small> </div> <p class="mb-1">{{post.description}}</p> <div class="d-flex w-100 justify-content-between"> <small>read more...</small> <div> <i title="Edit" class="fas fa-edit" aria-hidden="true"></i> <i title="Delete" class="fas fa-trash-alt" aria-hidden="true"></i> </div> </div> </a> </div> |
Сохраните указанные выше изменения и перезапустите клиентское приложение. Войдите в приложение, и вы сможете увидеть иконки редактирования и удаления, которые соответствуют каждому опубликованному в блоге посту.
Заполнение редактируемой информации во всплывающем окне
Когда пользователь нажимает на иконку редактирования, соответствующую любому посту в блоге, нам нужно заполнить данные в окне редактирования поста. Добавьте метод клика к иконке редактирования.
1 |
<i title="Edit" class="fas fa-edit" (click)="editPost(post)" aria-hidden="true"></i> |
Внутри CommonService нам необходимо определить наблюдаемый объект, чтобы отслеживать, когда будет нажата кнопка редактирования:
1 |
public postEdit_Observable = new Subject(); |
Определите еще одну переменную, чтобы отслеживать, когда пост будет отредактирован:
1 2 3 4 |
public post_to_be_edited; constructor(){ this.post_to_be_edited = new Post(); } |
Каждый раз, когда нажимается кнопка редактирования, пост будет редактироваться в CommonService, и мы также будем запускать наблюдаемый объект, чтобы уведомлять о редактировании поста. Определите два метода, чтобы настроить редактирование поста и уведомление об изменениях в посте.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
notifyPostEdit(){ this.postEdit_Observable.next(); } setPostToEdit(post: Post){ this.post_to_be_edited = post; this.notifyPostEdit(); } <pre class="lang:JS"> <p>Внутри метода клика мы вызываем метод setPostToEdit из CommonService. Вот как выглядит метод editPost:</p> <pre class="lang:JS"> editPost(post: Post){ this.commonService.setPostToEdit(post); } |
Когда пользователь нажимает кнопку редактирования, мы будем получать информацию в общей службе. Чтобы вывести всплывающее окно для обновления поста, нам нужно программно нажать кнопку добавления поста. Внутри файла home/home.component.html добавьте к кнопке добавления поста идентификатор #.
1 2 3 |
<button #addPost type="button" class="btn btn-link" data-toggle="modal" data-target="#exampleModal"> Add </button> |
Импортируйте ViewChild и ElementRef в файл home.component.ts.
1 |
import { Component, ViewChild, ElementRef } from '@angular/core'; |
Определите ссылку на кнопку добавления в файле home.component.ts.
1 |
@ViewChild('addPost') addBtn: ElementRef; |
Внутри конструктора HomeComponent подпишитесь на postEdit_Observable из CommonService. При выполнении обратного вызова подписки postEdit_Observable вызовите клик кнопки добавления, чтобы отобразить всплывающее окно. Вот как будет выглядеть файл home.component.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import { Component, ViewChild, ElementRef } from '@angular/core'; import { CommonService } from '../service/common.service'; @Component({ selector: 'app-home', templateUrl: './home.component.html', styleUrls: ['./home.component.css'] }) export class HomeComponent { @ViewChild('addPost') addBtn: ElementRef; constructor(private commonService: CommonService){ this.commonService.postEdit_Observable.subscribe(res => { this.addBtn.nativeElement.click(); }); } } |
Нам нужно подписаться на postEdit_Observable в файле add-post.component.ts, чтобы настроить редактирование поста для переменной post. Вот как выглядит метод ngOnInit в add-post.component.ts:
1 2 3 4 5 |
ngOnInit(){ this.commonService.postEdit_Observable.subscribe(res => { this.post = this.commonService.post_to_be_edited; }); } |
Сохраните указанные выше изменения и перезапустите клиентский сервер. Войдите в приложение и нажмите на кнопку редактирования возле любого поста в блоге. Вы сможете просмотреть информацию поста, заполненную во всплывающем окне добавления поста.
Создание API REST для обновления поста
Внутри server/app.js давайте определим еще одну конечную точку REST API для обновления информации поста на основе идентификатора. Вот как это должно выглядеть:
1 2 3 |
app.post('/api/post/updatePost', (req, res) => { }) |
Давайте сначала используем Mongoose для подключения к базе данных MongoDB.
1 2 3 4 5 |
app.post('/api/post/updatePost', (req, res) => { mongoose.connect(url, { useMongoClient: true }, function(err){ console.log('connection established'); }); }) |
После установления соединения мы используем метод обновления в модели Post.
1 2 3 4 5 6 |
Post.update( {_id: req.body.id }, { title : req.body.title, description: req.body.description }, (err, doc) => { if(err) throw err; }) |
Мы будем обновлять пост на основе отправленного идентификатора поста. Как видно из приведенного выше кода, мы указали для обновления post _id. Во втором параметре мы указали поля для обновления, title и description.
После обновления данных мы возвращаем status вместе с количеством строк, затронутых во время обновления. Вот как выглядит конечная точка REST API для обновления поста:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
app.post('/api/post/updatePost', (req, res) => { mongoose.connect(url, { useMongoClient: true }, function(err){ if(err) throw err; Post.update( {_id: req.body.id }, { title : req.body.title, description: req.body.description }, (err, doc) => { if(err) throw err; return res.status(200).json({ status: 'success', data: doc }) }) }); }) |
Выполнение вызова REST API для обновления
Идентификатор, возвращаемый из MongoDB для каждого поста, равен _id, поэтому нам нужно изменить идентификатор модели src/app/models/post.model.ts. Вот как это выглядит:
1 2 3 4 5 6 7 8 9 10 |
export class Post { constructor(){ this._id = ''; this.title = ''; this.description = ''; } public _id; public title; public description; } |
Когда мы нажимаете кнопку добавления поста, метод вызывает addPost. Внутри метода addPost в add-post.component.ts мы проверяем, имеет ли объект post _id. Если _id присутствует, нам необходимо вызвать метод обновления из службы, в противном случае мы вызываем метод службы добавления поста. Создайте внутри файла add-post.service.ts метод updatePost.
1 2 3 4 5 6 7 |
updatePost(post: Post){ return this.http.post('/api/post/updatePost',{ id: post._id, title : post.title, description : post.description }) } |
Вот как будет выглядеть измененный метод addPost в файле add-post.component.ts:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
addPost() { if(this.post.title && this.post.description){ if(this.post._id){ this.addPostService.updatePost(this.post).subscribe(res =>{ this.closeBtn.nativeElement.click(); this.commonService.notifyPostAddition(); }); } else { this.addPostService.addPost(this.post).subscribe(res =>{ this.closeBtn.nativeElement.click(); this.commonService.notifyPostAddition(); }); } } else { alert('Title and Description required'); } } |
Сохраните приведенные выше изменения и перезапустите серверы Angular и Node. Войдите в приложение и попробуйте отредактировать пост. При нажатии кнопки редактирования появится всплывающее окно для редактирования информации. Нажмите кнопку добавления, и информация будет обновлена и отображена в списке постов блога.
Заключение
В этом руководстве мы реализовали функционал для обновления существующих постов блога. Мы создали базовую конечную точку REST API, чтобы обновлять данные блога, основываясь на ID поста. Мы использовали клиент Mongoose для обновления информации поста в базе данных MongoDB. В следующей части мы будем использовать функции удаления и выхода из системы. Исходный код этого руководства доступен на GitHub.
Автор: Roy Agasthyan
Источник: //code.tutsplus.com/
Редакция: Команда webformyself.