在实际的前后台对接过程中,后台更倾向于把原始的数据发送给前台。比如教师性别字段,往往返回给前台是`0`和`1`,而不是`男`和`女`。前台接收到原始值以后按实际的需求展示。 ## 使用boolean值表示男女 我们打开C层文件`app.component.ts`,将其中的性别由字符串类型修改为boolean类型。 ```typescript // 定义教师数组 teachers = [{ id: 1, name: '张三', username: 'zhangsan', email: 'zhangsan@yunzhiclub.com', sex: true ❶ }, { id: 2, name: '李四', username: 'lisi', email: 'lisi@yunzhiclub.com', sex: false, ❶ }]; ``` * ❶ true表示男,false表示女。 ![](https://img.kancloud.cn/0d/c3/0dc32f524935dc96fa5ae48be85958e7_439x97.png) ## *ngIf 上节中我们学习了Angular的内置指令`*ngFor`,本节我们使用`*ngIf`来显示性别。`*ngIf`的使用方法非常的简单。 ```html <table> <tr> <th>序号</th> <th>姓名</th> <th>用户名</th> <th>邮箱</th> <th>性别</th> <th>操作</th> </tr> <tr *ngFor="let teacher of teachers; index as i"> <td>{{ i + 1 }}</td> <td>{{ teacher.name }}</td> <td>{{ teacher.username }}</td> <td>{{ teacher.email }}</td> <td *ngIf="teacher.sex❶">男</td> <td *ngIf="!teacher.sex❷">女</td> <td>删除</td> </tr> </table> ``` ![](https://img.kancloud.cn/97/4d/974dc221b40e7f30b7eca860a8322e8e_433x95.png) * ❶ `teacher.sex`为真时显示宿主标签 * ❷ `teacher.sex`为假时显示宿主标签 ## 结构化 上述的实现方案并不理想,原因是其破坏了代码的`结构`,这很容易团队中的其它小伙伴(包括一段时间后的自己)带来误伤。 其原因是上述代码`table`中的第一个`tr`中我们输出了5个`th`,但却在第二个`tr`中输出了6个`td`。而标准的HTML来中如果表格中的行列没有经过合并,则第行中的列数必然是相等的,如果不相等则可以认为发生了错误。虽然我们是在使用Angular框架,其能够动态的规划HTML,但仍然不应该在模块中给别人造成误读,或者说仍然不应该给团队中的其它成员增加阅读代码的成本。 如果将代码改成如下这样,则规避了上述误会。 ```html <tr *ngFor="let teacher of teachers; index as i"> <td>{{ i + 1 }}</td> <td>{{ teacher.name }}</td> <td>{{ teacher.username }}</td> <td>{{ teacher.email }}</td> <td> <span *ngIf="teacher.sex">男</span> <span *ngIf="!teacher.sex">女</span> </td> <td>删除</td> </tr> ``` ![](https://img.kancloud.cn/97/4d/974dc221b40e7f30b7eca860a8322e8e_433x95.png) 查看生成源码: ```html <td _ngcontent-a-c16=""> <span _ngcontent-a-c16="">男</span> ❶ <!--bindings={ "ng-reflect-ng-if": "true" }--> <!--bindings={ "ng-reflect-ng-if": "false" }--> </td> <td _ngcontent-a-c16=""> <!--bindings={ "ng-reflect-ng-if": "false" }--> <span _ngcontent-a-c16="">女</span> ❷ <!--bindings={ "ng-reflect-ng-if": "true" }--> </td> ``` * ❶ 第一个`*ngIf`生效时 * ❷ 第二个`*ngIf`生效时 * 😀 以注释出现的内容为angular自动生成,目的是帮助我们了解模板解析的过程 仔细观察我们能够轻易发现,在上述代码中我们增加了冗余的标签`<span>`。在大多数时候,这样做无可厚非。在有些时候,比如我们在`css`中对样式进行了精确的控制,则可能由于我们增加的这个`<span>`标签而导致样式失效。这时便可以使用`else`结合**永远不会显示出来**的`<ng-template>` ## else 与 ng-template 有`if`的地方,则必然可以使用`else`,Angular也不例外。 ```html <tr *ngFor="let teacher of teachers; index as i"> <td>{{ i + 1 }}</td> <td>{{ teacher.name }}</td> <td>{{ teacher.username }}</td> <td>{{ teacher.email }}</td> <td *ngIf="teacher.sex; else❶ femaleBlock❷">男</td>❹ <td>删除</td> </tr> </table> <ng-template❺ #femaleBlock❸> <td>女</td>❻ </ng-template> ``` * ❶ else关键字出现在`*ngIf`中 * ❷ 该名字自己随意起,作用是进行关键字的标识。当else条件成立时,Angular将按此标识去查找对应的元素(模板)。 * ❸ 与❷相对应,表示else成立时使用本元素来替换`*ngIf`的宿主元素❹ * ❺ `<ng-template>`具有**永远不会显示出来**的特性,所以当else成立时,在生成的HTML代码中也找不到`<ng-template>`的身影 * ❻ 做为`<ng-template>`中的内容,当else成立时,被用来替换`*ngIf`的宿主元素❹ ![](https://img.kancloud.cn/97/4d/974dc221b40e7f30b7eca860a8322e8e_433x95.png) 查看生成源码: ```html <td _ngcontent-a-c16="">男</td> ... <td _ngcontent-a-c16="">女</td> ``` 在源码出我们并没有找到任何关于`<ng-template>`的信息,也印证了其**永远不会显示出来**的特性。 好了,休息,休息一会。 # 本节作业 请阅读官方文档中的[NgSwitch指令](https://www.angular.cn/guide/built-in-directives#the-ngswitch-directives),**尝试**使用 `ngSwitch` 来显示性别。 # 资源列表 | 名称 | 地址 | |---- | ---- | | API -> NgIf | [https://www.angular.cn/api/common/NgIf](https://www.angular.cn/api/common/NgIf) | | 内置指令 -> NgIf | [https://www.angular.cn/guide/built-in-directives#ngif](https://www.angular.cn/guide/built-in-directives#ngif) | | <ng-template>元素 | [https://www.angular.cn/guide/structural-directives#the-ng-template](https://www.angular.cn/guide/structural-directives#the-ng-template) | 本节源码 | [https://github.com/mengyunzhi/angular11-guild/archive/step2.1.4.zip](https://github.com/mengyunzhi/angular11-guild/archive/step2.1.4.zip)