让我们创建一个
Angular组件,以从特定逻辑组创建一组复选框。 该组件将使用重用思想编写。 这是什么意思? 下面是一个示例:
假设您有编辑用户的任务。 编辑时,通常会打开一个包含所有字段的表单。 用户可以从
“ Adimin”,“ Director”,“ Professor”,“ Student”列表中扮演一个或多个角色
。为了实现角色的多种选择,决定为每个角色绘制一个复选框。 通过选中或取消选中用户角色将更改。
首先,让我们创建一个父组件(即表单的页面),该组件已经包含我们的
复选框组组件。
export class AppComponent implements OnInit , , , ]; public userModel = ; constructor() ngOnInit(): void }
如您所见,我对所有可能的角色进行了硬编码,但是在实际应用程序中,很可能会从数据库中请求角色。 为了模拟到服务器的HTTP,我将相同的值分配给另一个变量,但要稍加延迟。
//app.component.ts userRolesOptions = new Array<any>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles; }, 1000); // 1 }
现在让我们开始创建一个通用的checkbox-group组件,当需要一个来自复选框的组时,可以在
没有任何问题的情况下
重用它。
首先,我们需要一个这样的类CheckboxItem.ts
export class CheckboxItem { value: string; label: string; checked: boolean; constructor(value: any, label: any, checked?: boolean) { this.value = value; this.label = label; this.checked = checked ? checked : false; } }
CheckboxComponent将使用它呈现所有可能的选择(在我们的示例中为角色)并从状态保存(选择或不选择该选项)。 请注意,“ checked”属性是构造函数中的可选参数,默认为false,也就是说,不会首先选择所有值。 当我们创建一个没有单个角色的新用户时,这是合适的。
接下来,我们将略微修改模拟服务器请求的函数,以便我们可以在JSON响应和Array之间进行映射
userRolesOptions = new Array<CheckboxItem>(); ngOnInit(): void { setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name)); }, 1000); }
服务器返回给我们的JSON结构无关紧要。 每个HTML复选框始终具有一个值和一个描述。 在我们的例子中,我们将“ id”与“ value”映射,将“ name”与“ label”映射。
值将用作该选项的键或ID,
标签只是用户读取的描述字符串。
下一步是创建一个CheckboxGroupComponent。 他看起来像这样:
@Component({ selector: 'checkbox-group', templateUrl: './checkbox-group.component.html', styleUrls: ['./checkbox-group.component.css'] }) export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); constructor() { } ngOnInit() {} }
这不是Angular教程,因此我不会解释该框架的细节。 谁需要阅读官方文档。
名为
options的
@Input属性将包含默认情况下未选中的所有可能值的列表。 我们的HTML组件模板将呈现此列表包含的复选框。
这是CheckboxGroupComponent的html:
<div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked”>{{item.label}} </div>
注意,我使用ngModel绑定了
选项列表中的每个
“ checked” 项目属性。
最后一步是将我们新创建的组件添加到父AppComponent模板。
// somewhere in AppComponent html template <checkbox-group [options]=”userRolesOptions”></checkbox-group>
结果应该是这样的:

为了获得所有当前选定的选项,我们将创建一个Output事件,单击任何一个复选框,将返回我们的选定列表。 像这样:[1,2,4]
在CheckboxGroupComponent模板中,我们将
change事件与新函数相关联。
<div *ngFor=”let item of options”> <input type=”checkbox” [(ngModel)]=”item.checked” (change)=”onToggle()”>{{item.label}} </div>
现在是实现此功能的时候了:
export class CheckboxGroupComponent implements OnInit { @Input() options = Array<CheckboxItem>(); @Output() toggle = new EventEmitter<any[]>(); constructor() {} ngOnInit(){} onToggle() { const checkedOptions = this.options.filter(x => x.checked); this.selectedValues = checkedOptions.map(x => x.value); this.toggle.emit(checkedOptions.map(x => x.value)); } }
在AppComponent模板中订阅此事件(名称为
toggle的 Output属性)。
<checkbox-group [options]=”userRolesOptions” (toggle)=”onRolesChange($event)”></checkbox-group>
并在userModel中分配返回结果(选定角色)。
export class CheckboxGroupComponent implements OnInit { //.. onRolesChange(value) { this.userModel.roles = value; console.log('Model role:' , this.userModel.roles); } }
现在,每次单击复选框时,您都会在控制台中看到选定角色的列表。 更确切地说,是他们的ID。 例如,如果我选择角色
Admin和
Professor ,则会得到“模型角色:(2)[1,3]”。
该组件即将完成,可以重复使用。 剩下的最后一件事是提供复选框组初始化支持。 在我们进行用户编辑的情况下,这是必需的。 在此之前,我们需要向服务器发出请求以获取当前用户角色列表并初始化CheckboxGroupComponent。
我们有两种方法可以做到这一点。
第一种是使用CheckboxItem类的构造函数,并使用可选的“ checked”参数。 在我们进行映射的地方。
//AppComponent.ts setTimeout(() => { this.userRolesOptions = this.userRoles.map(x => new CheckboxItem(x.id, x.name, true)); }, 1000); //
第二种方法是添加另一个
selectedValues列表来初始化我们的组件。
<checkbox-group [options]=”userRolesOptions” [selectedValues]=”userModel.roles” (toggle)=”onRolesChange($event)”></checkbox-group>
假设我们已经向当前用户发出了请求,并且数据库中有一个具有三个角色的模型。
//AppComponent.ts public userModel = { id: 1, name: 'Vlad', roles: [1,2,3] }; constructor() { } //rest of the code
在CheckboxGroupComponent中,如果角色ID包含在
selectedValues列表中,则将每个复选框的所有“选中”属性初始化为true。
//CheckboxGroupComponent.ts ngOnInit() { this.selectedValues.forEach(value => { const element = this.options.find(x => x.value === value); if (element) { element.checked = true; } }); }
结果,您应该得到以下结果:
在这里,我使用了Angular Material中的样式在启动时,Angular将在页面上绘制所有复选框之前会延迟一秒钟。 这模拟了从数据库加载角色所花费的时间。
重要的是要注意,您可以通过订阅事件(切换)来获得所有选定的角色,或者只需使用位于
父组件中的
userRolesOptions列表中的每个项目对象中的“ checked”属性
即可 。 这是因为到列表的链接是通过@Input(绑定)传递的,并且对象内的所有更改都将被同步。
const checkedOptions = this.userRolesOptions.filter(x => x.checked);
可以根据需要设置此类组件的样式,并用于需要多选的任何任务。
感谢您阅读本文! 我希望您喜欢将Angular组件用于可重用的想法。
PS:如果这篇文章很受欢迎,我将发布第二小部分,其中的同一示例使用Angular Reactive Forms编写。