展示用户列表

本节,我们将展示用户列表。当选中某个用户时,能够查看到该用户的详细信息。

创建模拟(mock)的用户数据

由于目前,我们的应用都是纯粹的客户端程序,并非涉及数据的存储以及接口的访问,所以,我们只能模拟(mock)一些用户列表数据。

在 src/app/ 文件夹中创建一个名叫 mock-users.ts 的文件。 定义一个包含十个用户的常量数组 USERS,并导出它。 该文件是这样的。

  1. import { User } from './user';
  2. export const USERS: User[] = [
  3. { id: 11, name: 'Way Lau' },
  4. { id: 12, name: 'Narco' },
  5. { id: 13, name: 'Bombasto' },
  6. { id: 14, name: 'Celeritas' },
  7. { id: 15, name: 'Magneta' },
  8. { id: 16, name: 'RubberMan' },
  9. { id: 17, name: 'Dynama' },
  10. { id: 18, name: 'Dr IQ' },
  11. { id: 19, name: 'Magma' },
  12. { id: 20, name: 'Tornado' }
  13. ];

展示用户列表

我们将要在 UsersComponent 的顶部显示这个用户列表。

打开 UsersComponent 类文件 src/app/users/users.component.ts ,并导入模拟的 USERS

  1. import { USERS } from '../mock-users';

往类中添加一个 users 属性,这样可以暴露出这些用户,以供后续绑定。

  1. users = USERS;

使用 *ngFor 列出这些用户

*ngFor 是一个 Angular 的复写器(repeater)指令。 它会为列表中的每项数据复写它的宿主元素。类似于 Java 或者 JavaScript 中的 for-each 循环。

用法如下:

  1. <li *ngFor="let user of users">

在这个例子中,

  • <li> 就是 *ngFor 的宿主元素
  • users 就是来自 UsersComponent 类的列表。
  • 当依次遍历这个列表时,user 会为每个迭代保存当前的用户象。

效果如下:

展示用户列表 - 图1

完整代码如下:

  1. <h2>我的用户</h2>
  2. <ul class="users">
  3. <li *ngFor="let user of users">
  4. <span class="badge">{{user.id}}</span> {{user.name}}
  5. </li>
  6. </ul>

增加样式

目前,展示用户数据是没有问题了。只是不大美化,此时需要CSS来帮忙。

编辑 users.component.css ,添加如下样式:

  1. /* UsersComponent's private CSS styles */
  2. .selected {
  3. background-color: #CFD8DC !important;
  4. color: white;
  5. }
  6. .users {
  7. margin: 0 0 2em 0;
  8. list-style-type: none;
  9. padding: 0;
  10. width: 15em;
  11. }
  12. .users li {
  13. cursor: pointer;
  14. position: relative;
  15. left: 0;
  16. background-color: #EEE;
  17. margin: .5em;
  18. padding: .3em 0;
  19. height: 1.6em;
  20. border-radius: 4px;
  21. }
  22. .users li.selected:hover {
  23. background-color: #BBD8DC !important;
  24. color: white;
  25. }
  26. .users li:hover {
  27. color: #607D8B;
  28. background-color: #DDD;
  29. left: .1em;
  30. }
  31. .users .text {
  32. position: relative;
  33. top: -3px;
  34. }
  35. .users .badge {
  36. display: inline-block;
  37. font-size: small;
  38. color: white;
  39. padding: 0.8em 0.7em 0 0.7em;
  40. background-color: #607D8B;
  41. line-height: 1em;
  42. position: relative;
  43. left: -1px;
  44. top: -4px;
  45. height: 1.8em;
  46. margin-right: .8em;
  47. border-radius: 4px 0 0 4px;
  48. }

这些样式,只为 UsersComponent 组件所使用。

效果如下:

展示用户列表 - 图2

添加事件

点击用户列表中的某个用户时,该组件应该在页面底部显示所选用户的详情。

添加 click 事件绑定的方式如下:

  1. <li *ngFor="let user of users" (click)="onSelect(user)">

click 外面的圆括号会让 Angular 监听这个

  • 元素的 click 事件。 当用户点击 <li> 时,Angular 就会执行表达式 onSelect(user)。

    onSelect() 是 UsersComponent 上的一个方法,接下来就会实现它。 Angular 会把所点击的 <li> 上的 user 对象传给它,这个 user 也就是前面在 *ngFor 表达式中定义的那个。

    修改 src/app/users/users.component.ts 把该组件的 user 属性改名为 selectedUser ,但不要为它赋值。 因为应用刚刚启动时并没有所选用户。

    添加如下 onSelect() 方法,它会把模板中被点击的用户赋值给组件的 selectedUser 属性。

    1. selectedUser: User;
    2. onSelect(user: User): void {
    3. this.selectedUser = user;
    4. }

    同时修改 users.component.html,把 user 更名为 selectedUser:

    1. <h2>{{selectedUser.name}}</h2>
    2. <div><span>id: </span>{{selectedUser.id}}</div>
    3. <div>
    4. <label>name:
    5. <input [(ngModel)]="selectedUser.name" placeholder="name">
    6. </label>
    7. </div>

    此时如果刷新浏览器,会报如下错误:

    1. ERROR TypeError: "_co.selectedUser is undefined"

    错误原因是,模版中 selectedUser 的并未初始化,所以,selectedUser.name中的属性是空的。

    所以,我们要加多一个判断,该组件应该只有当 selectedUser 存在时才显示所选用户的详情。

    把显示用户详情的 HTML 包裹在一个

    中。 并且为这个 div 添加 Angular 的 *ngIf 指令,把它的值设置为 selectedUser 即可。

    1. <div *ngIf="selectedUser">
    2. <h2>{{selectedUser.name}}</h2>
    3. <div><span>id: </span>{{selectedUser.id}}</div>
    4. <div>
    5. <label>name:
    6. <input [(ngModel)]="selectedUser.name" placeholder="name">
    7. </label>
    8. </div>
    9. </div>

    当 selectedUser 为 undefined 时,ngIf 从 DOM 中移除了用户详情。当选中一个用户时,selectedUser 也就有了值,并且 ngIf 把用户的详情放回到 DOM 中。

    效果如下:

    展示用户列表 - 图3

    选中的样式

    目前,很难识别哪些用户是已经选中的。我们需要在选中的用户上添加选中的样式.selected

    这个样式已经在 users.component.css 定义了,所以只要实施他即可。我们需要做下判断,如果当前用户是选中的用户,该用户就添加 .selected 样式,负责就移除.selected 样式。

    那么如何实现判断呢?

    Angular 的 CSS 类绑定机制让根据条件添加或移除一个 CSS 类变得很容易。 只要把 [class.some-css-class]=”some-condition” 添加到你要施加样式的元素上就可以了。

    用法如下:

    1. [class.selected]="user === selectedUser"

    如果当前行的用户和 selectedUser 相同,Angular 就会添加 CSS 类 selected,否则就会移除它。

    完整代码如下:

    1. <h2>我的用户</h2>
    2. <ul class="users">
    3. <li *ngFor="let user of users"
    4. [class.selected]="user === selectedUser"
    5. (click)="onSelect(user)">
    6. <span class="badge">{{user.id}}</span> {{user.name}}
    7. </li>
    8. </ul>

    效果如下:

    展示用户列表 - 图4