多组件化开发
本节,要把原来的 UsersComponent 重构成为 UsersComponent、UserDetailComponent 两个组件。多组件开发的方式具有以下优势:
- 通过缩减 UsersComponent 的职责简化了该组件。
- 可以把 UserDetailComponent 改进成一个功能丰富的用户编辑器,而不用改动父组件 UsersComponent。
- 可以改进 UsersComponent,而不用改动用户详情视图。
- 可以在其它组件的模板中重复使用 UserDetailComponent。
创建 UserDetailComponent 组件
与 UsersComponent 的创建方式类似,我们使用 Angular CLI 创建一个名为 user-detail 的新组件。
ng generate component user-detail
CLI 创建了一个新的文件夹 src/app/user-detail/,并生成了 UserDetailComponent 的相关的四个文件。
ng generate component user-detail
CREATE src/app/user-detail/user-detail.component.html (30 bytes)
CREATE src/app/user-detail/user-detail.component.spec.ts (657 bytes)
CREATE src/app/user-detail/user-detail.component.ts (288 bytes)
CREATE src/app/user-detail/user-detail.component.css (0 bytes)
UPDATE src/app/app.module.ts (556 bytes)
编辑 user-detail.component.html
从 UsersComponent 模板的底部把表示用户详情的 HTML 代码剪切粘贴到所生成的 UserDetailComponent 模板中。
所粘贴的 HTML 引用了 selectedUser。 新的 UserDetailComponent 可以展示任意用户,而不仅仅所选的。因此还要把模板中的所有 selectedUser 替换为 user。
完工之后,UserDetailComponent 的模板应该是这样的:
<div *ngIf="user">
<h2>{{user.name}}</h2>
<div><span>id: </span>{{user.id}}</div>
<div>
<label>name:
<input [(ngModel)]="user.name" placeholder="name">
</label>
</div>
</div>
编辑 user-detail.component.ts
UserDetailComponent 模板中绑定了组件中的 user 属性,它的类型是 User
打开 UserDetailComponent 类文件 user-detail.component.ts ,并导入 User 符号。
import { User } from '../user';
user 属性必须是一个带有 @Input()
装饰器的输入属性,因为外部的 UsersComponent 组件将会绑定到它。就像这样:
<app-user-detail [user]="selectedUser"></app-user-detail>
修改 @angular/core 的导入语句,导入 Input 符号。
import { Component, OnInit, Input } from '@angular/core';
添加一个带有 @Input() 装饰器的 user 属性。
@Input() user: User;
完整代码如下:
import { Component, OnInit, Input } from '@angular/core';
import { User } from '../user';
@Component({
selector: 'app-user-detail',
templateUrl: './user-detail.component.html',
styleUrls: ['./user-detail.component.css']
})
export class UserDetailComponent implements OnInit {
@Input() user: User;
constructor() { }
ngOnInit() {
}
}
编辑 users.component.html
UserDetailComponent 的选择器是 'app-user-detail'。 把 <app-user-detail>
添加到 UsersComponent 模板 users.component.html 的底部,以便把用户详情的视图显示到那里。
把 UsersComponent.selectedUser 绑定到该元素的 user 属性,就像这样:
<app-user-detail [user]="selectedUser"></app-user-detail>
其中,[user]="selectedUser"
是 Angular 的属性绑定语法。
这是一种单向数据绑定。从 UsersComponent 的 selectedUser 属性绑定到目标元素的 user 属性,并映射到了 UserDetailComponent 的 user 属性。
现在,当用户在列表中点击某个用户时,selectedUser 就改变了。 当 selectedUser 改变时,属性绑定会修改 UserDetailComponent 的 user属性,UserDetailComponent 就会显示这个新的用户信息。
修改后的 UsersComponent 的模板 users.component.html 是这样的:
<h2>我的用户</h2>
<ul class="users">
<li *ngFor="let user of users"
[class.selected]="user === selectedUser"
(click)="onSelect(user)">
<span class="badge">{{user.id}}</span> {{user.name}}
</li>
</ul>
<app-user-detail [user]="selectedUser"></app-user-detail>
运行
执行 ng serve
命令以启动应用。效果如下: