# 插值与模板表达式 在更新以前,我们需要根据ID获取到原教师的数据信息,我们为大家在后台内置了两个教师(还包括一些同学们后来添加的数据):id为1的张三以及id为2的李四。在此我们假设用户访问http://localhost:4200/edit/2来尝试编辑李四的基本信息。 > 为了减轻些服务器压力,后台的数据每天凌晨重置一次。 ## 获取教师信息 获取某个教师的接口信息如下: ```bash GET /teacher/{id} ``` | **类型Type** | **名称Name** | **描述Description** | **类型Schema** | | ------------ | ------------ | ------------------- | ------------------------------------------------------------ | | Response | | | `{id: number, username: string, name: string, email: string, sex: boolean}` | 根据接口,我们简单整理思路如下: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -13,7 +13,9 @@ export class EditComponent implements OnInit { ngOnInit(): void { const id = this.activeRoute.snapshot.params.id; - console.log('获取到的路由参数id值为', id); + + // 拼接请求URL + // 发起请求,成功时并打印请求结果,失败时打印失败结果 } } ``` 我们在正式编辑前用注释的方式给出了编程的思路,这是个非常好且应该保持习惯。有些事情,不要因为感觉简单就不想做。我们之所以写**优秀、易读**的代码,是为使以后的变更、阅读更轻松。对于我们而言,只有**变化**是永远不变的。我们应该以敞开的心态去迎接变化,而不是报怨,因为报怨解决不了任何问题,它的唯一作用便是使原本愉悦的心情变糟糕。 根据注释添加代码后,最后的代码如下: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -1,5 +1,6 @@ import {Component, OnInit} from '@angular/core'; import {ActivatedRoute} from '@angular/router'; +import {HttpClient} from '@angular/common/http'; @Component({ selector: 'app-edit', @@ -8,12 +9,22 @@ import {ActivatedRoute} from '@angular/router'; }) export class EditComponent implements OnInit { - constructor(private activeRoute: ActivatedRoute) { + constructor(private activeRoute: ActivatedRoute, + private httpClient: HttpClient) { } ngOnInit(): void { const id = this.activeRoute.snapshot.params.id; - console.log('获取到的路由参数id值为', id); + + // 拼接请求URL + const url = 'http://angular.api.codedemo.club:81/teacher/' + id; + // 发起请求,成功时并打印请求结果,失败时打印失败结果 + this.httpClient.get(url) + .subscribe((data) => { + console.log('成功', data); + }, (error) => { + console.log('失败', error); + }); } } ``` 当回调函数中仅有一个参数时,我们可以省略包含参数的`()`,所以上述请求代码还可以简化为: ```typescript this.httpClient.get(url) - .subscribe((data) => { + .subscribe(data => { console.log('成功', data); - }, (error) => { + }, error => { console.log('失败', error); }); } ``` 同时,当回调函数方法体中的代码仅有一行时,还可以省略包含方法体的`{}`,同时删除那仅有一行的代码的结束符`;`,则上述代码还可以简化为: ```typescript this.httpClient.get(url) - .subscribe(data => { - console.log('成功', data); - }, error => { - console.log('失败', error); - }); + .subscribe(data => + console.log('成功', data) + , error => + console.log('失败', error) + ); } ``` 如果这一行代码不长,我们还可以将其写到一行当中: ```typescript this.httpClient.get(url) - .subscribe(data => - console.log('成功', data) - , error => - console.log('失败', error) + .subscribe(data => console.log('成功', data), + error => console.log('失败', error) ); } ``` 当然了,掌握了这个原则上,你可以在以提升代码易读性为目的前提下,按自己的喜好随意改写。 ![image-20210227094238814](https://img.kancloud.cn/7b/1e/7b1ec97b8f53ae4b175a45d8c863cc3d_1926x682.png) ## 插值与模板表达示 在控制台中查看数值是个不错的习惯,但有时候不够直观。接下来,我们将后台请求回的数据直接显示在V层,以达到快速便捷查看的目的。组件中的`public`变量通行为V层与C层之间,若要V层中显示,则可以可以在C层中定义`public`类型的变量即可: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -8,7 +8,7 @@ import {HttpClient} from '@angular/common/http'; styleUrls: ['./edit.component.css'] }) export class EditComponent implements OnInit { - + 👉 public teacher: any; constructor(private activeRoute: ActivatedRoute, private httpClient: HttpClient) { } ``` 在typescript中,声明`public`类型的属性还可以省略该关键字,所以我们在声明`public`属性时,更愿意省略`public`关键字: ```typescript - public teacher: any; + teacher: any; ``` > 在这里我们将`teacher`类型声明为`any`,表示其可以是任意类型。后期我们将逐步修正此写法。在生产项目中,我们有时候会临时使用`any`来声明一些暂时未知的类型。 然后将请求成功获取的数据放到`teacher`属性中: ```typescript +++ b/first-app/src/app/edit/edit.component.ts @@ -20,7 +20,7 @@ export class EditComponent implements OnInit { const url = 'http://angular.api.codedemo.club:81/teacher/' + id; // 发起请求,成功时并打印请求结果,失败时打印失败结果 this.httpClient.get(url) - .subscribe(data => console.log('成功', data), + .subscribe(data => this.teacher = data, error => console.log('失败', error) ); } ``` 并使用**插值{{}}**与**模板表达式**将其显示在V层: ```typescript +++ b/first-app/src/app/edit/edit.component.html @@ -1,3 +1,4 @@ +{{teacher | json}} <div> 姓名:<input value="张三"> </div> ``` `{{}}`被称为插值表达式,`|`则是模板表达式中的一个。`|`又被称为管道(pipe)符,这里的`json`则是Angular内置的管道之一,起的作用是将JSON对象转换为JSON字符串。通常被我们用于在V层中快速查看JSON对象的值: ​ ![image-20210227100133772](https://img.kancloud.cn/e0/0f/e00f461b89970e5036d4d4ba0e3f94bc_1480x204.png) ## 本节作业 请尝试使用`[(ngModel)]`其绑定到`src/app/edit/edit.component.html`的`input`标签上。 ![image-20210227100611175](https://img.kancloud.cn/7f/29/7f293b24ccf2ae41e999b7a7228d0869_1330x462.png) 你可能需要如下代码: ```typescript // 发起请求,成功时并打印请求结果,失败时打印失败结果 - this.httpClient.get(url) + this.httpClient.get<any>(url) .subscribe(data => this.teacher = data, error => console.log('失败', error) ); ``` 其它的知识点请参考已学习的章节。请完成该作业后继续学习。 | 名称 | 地址 | 备注 | | ---------------- | ------------------------------------------------------------ | ---- | | 插值与模板表达式 | [https://angular.cn/guide/interpolation#template-expressions](https://angular.cn/guide/interpolation#template-expressions) | | | JSON管道 | [https://angular.cn/api/common/JsonPipe](https://angular.cn/api/common/JsonPipe) | | | 本节源码 | [https://github.com/mengyunzhi/angular11-guild/archive/step2.4.3.zip](https://github.com/mengyunzhi/angular11-guild/archive/step2.4.3.zip) | |