欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 Angular:请求 有大用

   先花点时间理解一下服务端应用提供的各种不同类型的接口的用法。然后再了解一下使用 Http 客户端上的 post 方法发送一些数据给服务端。服务端把它们存储起来。创建一个组件可以显示这些数据,在组件里用 Http 客户端的 get 方法去获取到需要的数据。用 delete 方法可以请求删除服务端上的数据。

创建一个内容编辑组件,组件上面添加一个表单,请求服务端应用,获取到数据以后,自动填写表单上的内容,用户修改了表单内容以后,按一下更新按钮,可以使用 Http 客户端的 put 方法,请求更新这个内容。

封面摄影: alfonso maseda varela

来自  https://ninghao.net/course/7756#info



# ng generate component modules/user/components/my-list            #生成一个组件my-list            

CREATE src/app/modules/user/components/my-list/my-list.component.html (22 bytes)

CREATE src/app/modules/user/components/my-list/my-list.component.spec.ts (600 bytes)

CREATE src/app/modules/user/components/my-list/my-list.component.ts (278 bytes)

CREATE src/app/modules/user/components/my-list/my-list.component.css (0 bytes)

UPDATE src/app/modules/user/user.module.ts (558 bytes)




# ng generate component modules/post/components/post-edit            #生成一个名为post-edit的组件

CREATE src/app/modules/post/components/post-edit/post-edit.component.html (24 bytes)

CREATE src/app/modules/post/components/post-edit/post-edit.component.spec.ts (614 bytes)

CREATE src/app/modules/post/components/post-edit/post-edit.component.ts (286 bytes)

CREATE src/app/modules/post/components/post-edit/post-edit.component.css (0 bytes)

UPDATE src/app/modules/post/post.module.ts (790 bytes)




介绍与准备

1)介绍(请求)


先花点时间理解一下服务端应用提供的各种不同类型的接口的用法。然后再了解一下使用 Http 客户端上的 post 方法发送一些数据给服务端。服务端把它们存储起来。创建一个组件可以显示这些数据,在组件里用 Http 客户端的 get 方法去获取到需要的数据。用 delete 方法可以请求删除服务端上的数据。

创建一个内容编辑组件,组件上面添加一个表单,请求服务端应用,获取到数据以后,自动填写表单上的内容,用户修改了表单内容以后,按一下更新按钮,可以使用 Http 客户端的 put 方法,请求更新这个内容。

来自  https://ninghao.net/video/7758#info


2)理解服务端应用的接口


在这个内容列表的列表项目里面,添加一个 Add to list 按钮,点击这个按钮,可以请求对应的服务端应用接口,把当前这个项目存储到一个地方。

在我们的演示用的服务端应用里可以添加一个这样的接口,回到项目,打开 db.json ,在这个文件里添加一个 "my-list",它的值是一个数组,这样服务端应用里就有了一个演示用的 my-list 接口了。

可以先去试一下,打开一个桌面版的 Http 客户端 ( Insomnia ),准备一个请求,给服务端发送数据,一般用的方法是 HTTP 的 POST,请求的地址就是接口的地址,这里就是 http://localhost:3000/my-list,这个 my-list 是刚才我们添加的一个接口。

我用的是postman

image.png

往它上面发送数据,在请求里可以包含一个主体 Body,数据的格式选择 JSON,在下面准备一个要发给后端服务的 JSON 格式的数据,里面添加一个 title 属性,设置一下对应的值。再添加一个 body 属性,随便修改点内容。

准备好以后就可以发送一下这个请求。

回到项目,看一下 db.json,你会发现,在 my-list 里面,会出现一个数据项目,这个就是我们通过桌面版的 Http 客户端发送给服务端的数据,服务端应用收到了请求,会把数据存储起来。真正的服务端应用,这个数据会存储到数据库系统里,并且可能会先要验证用户的登录状态。

我们准备的这个演示用的服务端应用,默认不会做检查,直接就把数据存储到这个 db.json 文件里了。

GET

想从接口获取到数据,可以使用 GET 方法请求这个地址,这里输出的就是服务端接口响应回来的数据列表。把这个请求访问再换成 POST,修改一下要发送的数据里的 title 的值,然后再发送一下这个请求。

把方法换成 GET,重新再请求一下 my-list,这次接口返回了两个数据项目。回到项目再看一下 db.json 文件,这里会出现刚才发送的内容项目。

PUT

修改数据项目,一般用 PUT 或者 PATCH 方法,请求的地址是 my-list 后面再加上一个数据项目的 id 号。请求里面也需要提供一个数据项目,修改一下 title 属性的值。 然后发送一下这个请求。

image.png

完成以后到 db.json 这里再检查一下,你会发现 id 号是 2 的数据项目,它的 title 的值会是刚才修改之后的值。

我们创建的服务端接口,使用 PUT 方法请求跟用 PATCH 方法请求会有些区别。

可以这样试一下,去掉这个要修改的数据里的 body 属性,修改一下它的 title 的值,然后再发送一下这个请求,

image.png

回到 db.json,你会发现,id 号是 2 的数据项目,它的 title 是我们修改之后的值,但是它之前的 body 属性不见了。

因为我们并没有在修改的数据里面,包含这个 body 的值。

在修改的数据里包含这个 body,然后再 send 一下这次请求。

image.png

这样 id 号是 2 的这个数据项目里,就又会包含一个 body 属性。

修改数据项目的值也可以使用 PATCH,把请求方法换成 PATCH,在请求的数据里只包含 title 属性,修改一下它的值,然后再发送一下这个请求。

image.png

你会发现,虽然我们在修改的数据里没有包含 body 属性,只包含了一个 title 属性,但是修改了这个数据项目之后,并没有删除掉在请求里不包含的属性。

DELETE

要想删除掉指定的数据项目,可以使用 HTTP 的 DELETE 方法,请求这个接口地址,就是 my-list 斜线,后面再加上要删除的数据项目的 id 号。发送一下这个请求。

image.png

这样就删除掉了 id 号是 2 的这个数据项目。再配置一个请求,用 DELETE 方法,请求 my-list/1 ,发送一下。这次就把 my-list 里的 id 号是 1 的数据项目给删除掉了。

image.png

总结

注意这里我们主要就是为了演示一下,一个一般的服务端接口的用法。以后在学习服务端应用开发的时候,我们会一起开发一个真正的可以使用的服务端应用。

来自  https://ninghao.net/video/7759#info


请求

3)POST:发送数据的请求


Angular 的 Http 客户端里面有个 post 方法可以给后端服务接口发送数据。在这个内容列表项目里面,可以添加一个按钮,点击这个按钮,会用 post 方法,把当前这个内容项目发送到指定的后端服务接口存储起来。

回到项目,先打开 PostService 这个服务,先在这个服务里添加一个方法,名字可以叫 addToList,方法接收一个 entity 参数,值的类型是 Post。方法的这个参数就是要发送给服务端的数据。

方法 return 的是,用一下 this.http 上的 post 这个方法,值的类型是 Post,注意这里这个 Post 指的是我们应用里的一种内容。

再把请求的地址,告诉 Http 客户端上的 post 方法,在上面可以添加一个属性,名字是 myListApi,对应的值是 http://localhost:3000/my-list 。

把这个 this.myListApi 交给 Http 客户端上的 post 这个方法,然后把要发送给服务端的数据也交给这个方法,这里就是 addToList 这个方法接收的 entity 这个参数的值。

组件

下面打开 PostItemComponent 组件,在这个组件里需要用到 PostService 服务上的方法,先把这个服务作为组件的依赖注入进来,在组件的构造方法里面,添加一个 private postService,类型是 PostService 。

然后在组件里再添加一个 addToList 方法,方法接收一个 entity 参数,值的类型是 Post。在这个方法里用一下 this.postService 服务上的 addToList 方法,把 entity 参数的值交给它,这个 entity 就是要发送给服务端的数据,接着再用一下 subscribe。

因为 Http 客户端上的这个 post 方法会返回 Observable,只有订阅了 Observable 以后它才能开始工作,也就是用 Http 的 post 方法发出请求。

视图

再打开这个组件的视图文件,可以再添加一个按钮元素,按钮上的文字是 Add to List , 绑定一下这个按钮上的 click,点击事件,点了它以后,执行组件里的 addToList 这个方法,再把 entity 的值交给这个方法。

预览

回到浏览器可以试一下,在这个内容列表里面,找到一个内容项目,点一下内容项目上的 Add to List 按钮,触发了按钮的点击事件,处理这个事件要执行的是组件里的 addToList 方法。

这个方法里面又用了一下 PostService 服务上的 addToList,这个方法里会使用 Http 客户端上的 post 方法,对我们的 my-list 这个接口发出请求,请求的时候会带着一个数据,这个数据就是当前点击 Add to List 按钮的数据项目。

打开 db.json 可以检查一下,这个文件可以看成是我们的服务端应用的数据库,在它的 my-list 这里,会出现刚才从前端那里发送过来的这个数据项目。

来自  https://ninghao.net/video/7761#info


4)我的内容列表组件(MyListComponent)


现在,这个 my-list 里面已经有数据了,下面可以去创建一个组件,利用一下服务端上的 my-list 里的数据。在终端,给项目生成一个组件,ng generate 一个 component ,放在 modules/user/components 里面,名字是 my-list 。

# ng generate component modules/user/components/my-list  (  ng g c modules/user/components/my-list   )

回到项目,打开 MyListComponent 组件,先在这个组件里添加一个属性,名字是 entities,它的值是一组 Post[],这个 entities 就是要在这个组件里显示的一组数据。也就是在 my-list 里面的数据。

服务

获取这些数据要请求服务端应用接口,这个工作可以交给一个服务去做,打开 PostService 服务,在这个服务里添加一个方法,方法的名字是 getMyList() ,在这个方法里 return 的是,用一下 this.http 上的 get 方法,值的类型是一组 Post ,把 my-list 接口的地址交给这个 get 方法。

组件

回到 MyListComponent 组件,在这个组件里要使用 PostService 服务上的方法,所以要把它作为这个类的依赖注入进来,在构造方法里,添加一个 private postService 类型是 PostService。

然后在组件的 ngOnInit 方法里,就是在组件初始化的时候,执行一下 this.postService 上的 getMyList 这个方法,这个方法返回的是 Observable,用一下 subscribe 订阅一下。

提供一个方法参数,Observable 上生产出来的数据可以叫它 data ,然后让 this.entities 的值等于这个 data。这里这个 data 的值就是用 Http 客户端上的 get 方法,请求 my-list 接口返回来的东西。

视图

打开 MyListComponent 组件的模板文件,先添加一个标题,上面加上 title ,标题文字是 My List 。

下面添加一组 div,在这个元素引用一下 *ngFor 指令,let entity of entities,迭代一下组件里的 entities 这个属性。

里面包含一个标题元素,标题内容可以绑定输出 entity 里的 title 属性的值。 标题下面再添加一个图像元素,在它上面绑定一下 src 属性,值是 entity 里的 image 属性。 再绑定一个 alt 属性,值是 entity 里的 title 。

导航

打开项目里的 header 组件的模板文件,它里可以添加一个导航链接,链接文字是 My List,链接的地址是 my-list。

路由

再找到 user 模块里的路由模块,在它里面可以添加一条新的路由,添加一个新的路由项目,路由的 path 是 my-list,路由对应的 component,设置成 MyListComponent 。

预览

回到浏览器可以试一下,回到页面顶部,按一下导航栏上的这个 My List 链接,界面上显示的是 MyListComponent 组件的视图内容。

里面的数据项目是请求 my-list 接口返回来的东西。这个列表里的图片的宽度可以再调整一下,找到这个组件的样式表,在它里面添加一个 img ,设置一下它的 width ,值是 100% 。

再回到浏览器预览一下。

下面可以再添加两个数据项目,回到内容列表,找到列表里的某个内容项目,然后点一下它上面的这个 Add to List 按钮。

可以再找一个数据项目,然后按一下 Add to List 。

回到 My List ,你会发现,这回这里显示的这个内容列表里面就会多出两个项目。 可以再去看一下服务端应用里的数据,打开 db.json,在 my-list 里面,现在会有三个数据项目。这三个数据项目就是按了内容列表上的 Add to List,请求服务端的 my-list 接口发送过来的。

来自   https://ninghao.net/video/7762#info

5)DELETE:删除数据的请求


在 My List 页面上显示的这个内容列表项目里面可以再添加一个 Remove 按钮,点击这个按钮可以从 My List 里面删除掉当前这个数据项目。

回到项目,这个删除的动作也可以放在一个服务里面,打开 PostService 服务,在里面添加一个方法,名字是 removeItemFromList ,方法接收一个 entityId 这个参数,参数的类型是 number,这个 entityID 应该就是要删除掉的数据项目的 Id 号。

方法 return 一下,执行 this.http 上面的 delete ,对指定的接口发出一个 DELETE 请求,请求的接口地址是 this.myListApi 斜线,后面加上要删除掉的项目的 Id 号。

组件

打开 MyListComponent 组件,在这个组件里再添加一个方法,名字也可以叫 removeItemFromList,方法接收一个 entityId ,类型是 number,方法里面,用一下 this.postService 上面的 removeFromList ,把要删除的项目的 Id 号交给这个服务上的方法,这个方法会返回 Observable,所以可以用一下 subscribe 订阅一下它。

如果不执行它上面的 subscribe 订阅的话,这个 Observable 上面不会生产出数据。

提供一个方法参数,里面可以设置一下 this.entities 的值,它的值用一下 this.entities.filter 过滤出一些数据项目,item ,item.id 不等于 entityId 。

意思就是,从 this.entities 里面,过滤出,或者叫筛选出,除了被删除掉的那个数据项目以外的数据项目。

视图

再打开这个组件的模板文件,在它的模板文件里面,添加一个删除按钮,放在一个段落里面,按钮元素是 button,按钮上的文字是 Remove。

给它绑定一个 click 事件,点击这个按钮,就执行一下这个组件里的 removeItemFromList 这个方法,把 entity 的 id 交给这个方法。

预览

回到浏览器试一下这个功能。打开 My List, 找到从这个列表里删除掉的内容项目,按一下项目上的 Remove 按钮。这样会用 Http 客户端上的 delete 方法,请求服务端接口,从服务端的数据库里删除掉了对应的这个项目。

再把最后这个项目也删除掉。现在 db.json 里的 my-list 里面就没有东西了。

打开 Posts 页面,可以在内容列表里面,再找几个项目,按一下 Add to List,点击这个按钮会用 Http 客户端上的方法,把这个数据项目发给 my-list 这个接口。 这个接口会存储从前端那里发送过来的数据。

再打开 My List 页面,在这个页面上会显示 my-list 里的数据项目。

来自 https://ninghao.net/video/7763#info



内容编辑

6)内容编辑组件(PostEditComponent)


下面去创建一个编辑内容用的组件,在终端,执行 ng generate ,生成一个 component,放在 modules/post/components 的下面,名字是 post-edit。

# ng generate component modules/post/components/post-edit  ( #  ng g c modules/post/components/post-edit )

回到项目,可以先打开 Post 模块的路由模块,在这里先添加一条编辑内容用的路由,路由的 path 是 posts/:id/edit。路由对应的 component 设置成 PostEditComponent。

打开 PostDetailsComponent 组件的模板文件,在内容详情视图里面添加一个编辑内容用的链接,放在一个段落里面,一组 strong,里面再加上一组 small ,里面添加一组 a 标签,链接文字是 Edit,标签上使用 routerLink,地址是 ./edit 。

预览

回到浏览器可以预览一下,先打开一个内容项目,这里会有一个 Edit 链接,点击这个链接,打开的就是编辑这个内容的地址。上面显示的这行文字来自 PostEditComponent 组件的模板文件。

来自  https://ninghao.net/video/7765#info


7)内容编辑组件里的表单


在这个内容编辑组件里面可以添加一个编辑内容用的表单,打开这个组件,这个表单可以用 formBuilder 去创建一个,把它作为这个组件的依赖注入进来,private formBuilder,类型是 FormBuilder。

想在这个组件里使用这个东西还得在组件所属的模块里导入 ReactiveFormsModule 模块,打开 PostModule 模块,在它的 imports 里面,添加一个 ReactiveFormsModule ,它来自 @angular/forms 。

回到 PostEditComponent 组件,在组件里面,添加一个 postEditForm ,它的值用一下 this.formBuilder 上的 group 方法,给它一个对象,里面是表单里的一些元素。

内容有 title,image 还有 body 属性,所以在这个表单里也可以添加对应名字的表单元素,添加一个 title,一个数组,第一个项目是空白。再添加一个 body,它的初始值也是空白。最后再添加一个 image,一个数组,项目的默认的值也是空白。

模板

打开组件的模板文件,里面先用一组 form 元素,元素上面用一个 formGroup,值是组件里的 postEditForm。

表单里面添加几个表单元素,一组 label,一个段落,文字是 Title,下面放一个 text 类型的 input,在它上面还得用一下 formControlName,把 postEditForm 里的 title 绑定在这里。

复制一份,修改一下标签文字,换成 Image,再修改一下 formControlName 的值,换成 image。

下面再添加一个文本区域,一组 label ,标签文字是 Body,下面再添加一组 textarea,上面加上一个 formControlName ,值是 body 。

这个表单上可以再添加一个返回上一级路由的链接,一个段落,里面是 strong ,包装一个 small,它里面是个 a 标签,文字是 Back,链接上用一个 routerLink,值是 ../ 表示上一级路由。

在 form 上监听一下 ngSubmit 事件,用组件里的 onSubmit 方法处理提交表单。

回到组件,可以去添加需要的这个方法,名字是 onSubmit() ,这个方法做的事情,可以先简单的在控制台上输出表单里的值。console.log,输出 this.postEditForm.value 。

在这个表单里还得再添加一个提交按钮,放在一组段落标签里面,用一组 button 标签,文字是 Update,设置一下这个按钮的类型,type 等于 submit。

预览

在浏览器上可以预览一下这个编辑内容用的表单,随便在表单里输入点内容,然后按一下 Update 按钮,提交表单。控制台上会输出表单里面的当前的值。

这个文本区域的样式可以稍微改一下,回到项目,打开应用的全局样式表,找到这块设置 input 元素的样式,逗号分隔一下,里面再添加一个 textarea。

回到视图,在这个 textarea 元素上面,可以再用一个 rows 属性,它的值先设置成 10 。 然后再回到编辑内容页面预览一下这个编辑内容用的表单。

来自   https://ninghao.net/video/7766#info



8)预填内容编辑组件表单值


根据路由地址里的这个 Id 参数的值,可以请求服务端,获取到对应的内容数据,然后把数据值填到这个内容表单上。回到项目,打开 PostEditComponent 组件。

组件里要用到 route 还有 postService 服务,在构造方法里把它们注入进来,private route,类型是 ActivatedRoute 。再添加一个 private postService,类型是 PostService。

在组件的 ngOnInit 方法里面,也就是在初始化组件的时候,用一下 this.route.paramMap,它是一个 Observable,我们需要根据它上面的 id 参数值,去请求服务端应用得到对应的内容数据。

switchMap

先给它接上一个管道,用一下 pipe 方法,里面可以安排一个 switchMap 操作员,这个 switchMap 来自 rxjs/operators。

paramMap 这个 Observable 上生产出来的值,在这里可以得到,名字可以是 params ,方法让它返回另外一个 Observable,用一下 this.postService 服务上的 show 这个方法,这个方法返回的是使用了 Http 客户端的 get 方法返回的值,也就会是一个 Observable 。

准备一下方法需要的内容的 Id ,用 params 上的 get ,得到路由地址里的 id 参数的值,前面可以加上一个加号,把它转换成数字值。

接着再用一个 subscribe 订阅一下,提供一个方法,参数值的名字可以叫 data ,这个 data 值应该是 postService 上的 show 方法返回来的那个 Observable 上生产出来的数据,也就是请求服务端接口得到的响应数据。因为上面我们使用了swtichMap,

得到了响应的数据以后,用一下 this.postEditForm 上的 patchValue,把得到的数据交给这个方法。patchValue 还有 setValue 都可以设置表单的值。只不过 patchValue 更像是打补丁。

预览

回到浏览器先预览一下,现在这个内容编辑页面上的表单里面,就会出现当前要编辑的这个内容的值了。

来自   https://ninghao.net/video/7767#info


9)PUT:更新数据的请求


提交了这个表单可以发送一下更新内容的请求,先在 PostService 服务里添加一个更新内容用的方法,方法的名字可以是 update,接收一个 id 参数,它的值是要更新的内容的 Id 号,类型是 number ,还有一个 entity 参数,类型是 Post,这个 entity 里的东西应该就是要更新的具体的数据。

方法 return 的是 this.http,用一下 put 这个方法,值的类型是 Post。先把要请求的接口地址交给它,地址是 this.postApi 斜线,再加上一个 id 。第二个参数是要更新的具体的数据,这里就是 entity 。

组件

回到 PostEditComponent 组件,找到组件里的 onSubmit 方法,在这里用一下 this.postService 上的 update 方法,要给这个方法提供一个内容的 Id,可以用一下路由上的 id 参数,this.route,直接访问 snapshot 上的 paramMap ,用一下 get,得到 id 参数的值,最前面加上一个 + 号,把它转换成数字。

逗号分隔一下,第二个参数是具体的数据,这里用一下 this.postEditForm 上的 value 。接着再用一下 subscribe() 方法订阅一下这个请求 Observable 。

预览

回到浏览器试一下,可以修改一下这个内容的 Title,也就是它的标题内容,再修改一下它的 Body 的值,This image is shot by Bruce W.

按一下 Update ,提交这个表单,然后点一下这个返回链接。

你会发现,现在这个内容的标题,还有正文都是我们修改之后的内容了。

来自  https://ninghao.net/video/7768#info




普通分类: