在Angular博客教程系列的上一部分中,您学习了如何创建ShowPostComponent
来在主页上显示博客文章列表。 您使用创建的REST API端点获取了从MongoDB Shell中插入的记录。
在本教程中,您将创建一个名为AddPostComponent
的新组件,以提供用于将新博客帖子添加到MongoDB数据库的用户界面。
入门
让我们从克隆本系列前一部分的源代码开始。
git clone https://github.com/royagasthyan/ShowPost AddPost
导航到项目目录并安装所需的依赖项。
cd AddPost/client
npm install
cd AddPost/server
npm install
安装依赖项后,请重新启动客户端和服务器应用程序。
cd AddPost/client
npm start
cd AddPost/server
node app.js
将您的浏览器指向http:// localhost:4200 ,您应该正在运行该应用程序。
创建添加帖子组件
让我们开始创建AddPostComponent
。 在src/app
文件夹中创建一个名为add-post
的文件夹。 在add-post
文件夹中,创建一个名为add-post.component.ts
文件,并添加以下代码:
import { Component } from '@angular/core';
import { Post } from '../models/post.model';
@Component({
selector: 'app-add-post',
templateUrl: './add-post.component.html',
styleUrls: ['./add-post.component.css']
})
export class AddPostComponent {
constructor() {
}
}
创建一个名为add-post.component.html
的文件和以下HTML代码:
<div class="modal fade" id="exampleModal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
<button type="button" #closeBtn class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<form>
<div class="form-group">
<label for="exampleInputEmail1">Title</label>
<input name="title" type="text" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter title">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Description</label>
<textarea name="description" class="form-control" id="exampleInputPassword1" placeholder="Password">
</textarea>
</div>
<button type="button" class="btn btn-primary">Add</button>
</form>
</div>
</div>
</div>
</div>
您将把添加帖子组件显示为弹出窗口。
现在,您需要将AddPostComponent
添加到NgModule
。 导入AddPostComponent
在app.module.ts
文件。
import { AddPostComponent } from './add-post/add-post.component';
将组件添加到NgModule
declarations
列表中。 外观如下:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ROUTING } from './app.routing';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RootComponent } from './root/root.component';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
import { ShowPostComponent } from './show-post/show-post.component';
import { AddPostComponent } from './add-post/add-post.component';
@NgModule({
declarations: [
RootComponent,
LoginComponent,
HomeComponent,
ShowPostComponent,
AddPostComponent
],
imports: [
BrowserModule,
ROUTING,
FormsModule,
HttpClientModule
],
providers: [],
bootstrap: [RootComponent]
})
export class AppModule { }
要触发添加后弹出窗口,您已经将data-target
属性添加到home.component.html
的按钮。
<button type="button" class="btn btn-link" data-toggle="modal" data-target="#exampleModal">
Add
</button>
保存以上更改,然后重新启动应用程序。 登录该应用程序,然后单击主页中的“ 添加”链接。 您将把AddPostComponent
显示为弹出窗口。
![Angular Blog应用程序-添加帖子弹出窗口](https://i-blog.csdnimg.cn/blog_migrate/a2a04ab91a9eb48d0c4609bdae759472.png)
实施添加帖子功能
将ngModel
指令添加到输入元素以获取title
和description
。
<input name="title" type="text" [(ngModel)]="post.title" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" placeholder="Enter title">
<textarea name="description" [(ngModel)]="post.description" class="form-control" id="exampleInputPassword1" placeholder="Password">
</textarea>
将click
指令添加到按钮,以调用用于保存博客文章的方法。
<button (click)="addPost()" type="button" class="btn btn-primary">Add</button>
从add-post.component.ts
文件中的src/app/models/post.model.ts
导入Post
模型。
import { Post } from '../models/post.model';
在add-post.component.ts
文件中定义post
变量。
public post : Post;
在add-post.component.ts
文件中定义addPost
方法。 通过addPost
方法,您将验证输入的title
和description
,并调用service方法以调用REST API。 该方法的外观如下:
addPost() {
if(this.post.title && this.post.description){
// call the service method to add post
} else {
alert('Title and Description required');
}
}
让我们为组件AddPostComponent
创建服务文件。 创建一个名为add-post.service.ts
的文件,并添加以下代码:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Post } from '../models/post.model';
@Injectable()
export class AddPostService {
constructor(private http: HttpClient){
}
}
在AddPostService
内部,创建一个名为addPost
的方法以进行REST API调用。
addPost(post: Post){
return this.http.post('/api/post/createPost',{
title : post.title,
description : post.description
})
}
如上面的代码所示,您已经使用HttpClient
进行API调用并返回Observable
。
在addPost
方法内的add-post.component.ts
文件中,您将从add-post.service.ts
文件中订阅addPost
方法。
this.addPostService.addPost(this.post).subscribe(res =>{
// response from REST API call
});
这是add-post.component.ts
文件的外观:
import { Component } from '@angular/core';
import { AddPostService } from './add-post.service';
import { Post } from '../models/post.model';
@Component({
selector: 'app-add-post',
templateUrl: './add-post.component.html',
styleUrls: ['./add-post.component.css'],
providers: [ AddPostService ]
})
export class AddPostComponent {
public post : Post;
constructor(private addPostService: AddPostService) {
this.post = new Post();
}
addPost() {
if(this.post.title && this.post.description){
this.addPostService.addPost(this.post).subscribe(res =>{
console.log('response is ', res)
});
} else {
alert('Title and Description required');
}
}
}
创建用于添加帖子的REST API
让我们创建一个REST API端点,以将博客文章添加到MongoDB数据库中。 在server/app.js
文件中,创建一个API端点,如下所示:
app.post('/api/post/createPost', (req, res) => {
// insert the details to MongoDB
})
首先,您需要使用Mongoose
客户端连接到MongoDB数据库。
mongoose.connect(url, { useMongoClient: true }, function(err){
if(err) throw err;
console.log('connection established ');
});
建立连接后,您需要使用server/model/post.js
文件中定义的Post
模式创建模型对象。
const post = new Post({
title: req.body.title,
description: req.body.description
})
如上面的代码所示,您使用从请求req
对象传入的title
和description
创建了Post对象。
在Post对象上调用save
方法将条目保存到MongoDB。
post.save((err, doc) => {
if(err) throw err;
return res.status(200).json({
status: 'success',
data: doc
})
})
如上面的代码所示,调用save
方法回调没有错误后,它将返回success
消息以及返回的对象doc
。
REST API端点的外观如下:
app.post('/api/post/createPost', (req, res) => {
mongoose.connect(url, { useMongoClient: true }, function(err){
if(err) throw err;
const post = new Post({
title: req.body.title,
description: req.body.description
})
post.save((err, doc) => {
if(err) throw err;
return res.status(200).json({
status: 'success',
data: doc
})
})
});
})
保存以上更改,然后重新启动Angular和Node服务器。 登录到该应用程序,然后尝试添加新的博客文章。 单击添加按钮后,检查浏览器控制台,您将记录成功响应。
将博客文章详细信息成功添加到数据库后,您需要关闭弹出窗口。 为了关闭弹出窗口,有一个关闭按钮,您需要以编程方式单击该按钮。
您将使用@ViewChild
装饰器访问关闭按钮。
进口ViewChild
和ElementRef
在AddPostComponent
。
import { Component, ViewChild, ElementRef } from '@angular/core';
在AddPostComponent
内部,定义以下变量:
@ViewChild('closeBtn') closeBtn: ElementRef;
使用以下代码启动closeBtn
点击:
this.closeBtn.nativeElement.click();
将以上代码添加到addPost
方法的成功回调中。 这是add-post.component.ts
的addPost
方法。
addPost() {
if(this.post.title && this.post.description){
this.addPostService.addPost(this.post).subscribe(res =>{
this.closeBtn.nativeElement.click();
});
} else {
alert('Title and Description required');
}
}
保存更改并重新启动客户端服务器。 登录该应用程序,然后尝试添加新的博客文章。 成功保存博客文章详细信息后,弹出窗口将关闭。
刷新博客列表
要注意的一件事是,新添加的博客文章未显示在博客文章列表中。 因此,您需要添加触发器以通知何时更新ShowPostComponent
。 您将利用公共服务在两个组件之间进行通信。
在src/app
文件夹中创建一个名为service
的文件夹。 使用以下代码创建一个名为common.service.ts
的文件:
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class CommonService {
public postAdded_Observable = new Subject();
constructor(){
}
notifyPostAddition(){
this.postAdded_Observable.next();
}
}
如上面的代码所示,您已经声明了一个名为postAdded_Observable
的Subject
以跟踪新博客帖子添加到数据库中的情况。 每当将新博客帖子添加到数据库时,您都将调用notifyPostAddition
方法,该方法将通知订阅者有关更新。
导入CommonService
在app.module.ts
,它包括在NgModule
供应商的名单。 外观如下:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { ROUTING } from './app.routing';
import { FormsModule } from '@angular/forms';
import { HttpClientModule } from '@angular/common/http';
import { RootComponent } from './root/root.component';
import { LoginComponent } from './login/login.component';
import { HomeComponent } from './home/home.component';
import { ShowPostComponent } from './show-post/show-post.component';
import { AddPostComponent } from './add-post/add-post.component';
import { CommonService } from './service/common.service';
@NgModule({
declarations: [
RootComponent,
LoginComponent,
HomeComponent,
ShowPostComponent,
AddPostComponent
],
imports: [
BrowserModule,
ROUTING,
FormsModule,
HttpClientModule
],
providers: [CommonService],
bootstrap: [RootComponent]
})
export class AppModule { }
进口CommonService
在show-post.component.ts
文件并初始化它的构造方法。
import { CommonService } from '../service/common.service';
constructor(private showPostService: ShowPostService, private commonService: CommonService) {
}
在ngOnInit
方法内,订阅postAdded_Observable
变量并加载getAllPost
方法。 ngOnInit
方法的外观如下:
ngOnInit(){
this.getAllPost();
this.commonService.postAdded_Observable.subscribe(res => {
this.getAllPost();
});
}
进口CommonService
在add-post.component.ts
文件并调用notifyPostAddition
方法一旦博客文章已被添加。 这里是如何的addPost
从方法AddPostComponent
外观:
addPost() {
if(this.post.title && this.post.description){
this.addPostService.addPost(this.post).subscribe(res =>{
this.closeBtn.nativeElement.click();
this.commonService.notifyPostAddition();
});
} else {
alert('Title and Description required');
}
}
保存以上更改,然后重新启动客户端服务器。 登录到该应用程序并添加新的博客文章。 添加后,博客文章列表将使用新的博客文章进行更新。
包起来
在本教程中,您创建了AddPostComponent
以将博客文章详细信息添加到MongoDB数据库。 您创建了REST API,用于使用Mongoose
客户端将博客文章保存到MongoDB数据库中。
在本系列的下一部分中,您将实现编辑和更新博客文章详细信息的功能。
到目前为止,您的情况如何? 请在下面的评论中让我知道您的宝贵建议。