角度:创建适合重用的多个复选框组件

让我们创建一个Angular组件,以从特定逻辑组创建一组复选框。 该组件将使用重用思想编写。 这是什么意思? 下面是一个示例:

假设您有编辑用户的任务。 编辑时,通常会打开一个包含所有字段的表单。 用户可以从“ Adimin”,“ Director”,“ Professor”,“ Student”列表中扮演一个或多个角色

为了实现角色的多种选择,决定为每个角色绘制一个复选框。 通过选中或取消选中用户角色将更改。

首先,让我们创建一个父组件(即表单的页面),该组件已经包含我们的复选框组组件。

export class AppComponent implements OnInit { private userRoles = [ { id: 1, name: 'Admin' }, { id: 2, name: 'Director' }, { id: 3, name: 'Professor' }, { id: 4, name: 'Student' } ]; public userModel = { id: 0, name: "", roles: [] }; 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。 例如,如果我选择角色AdminProfessor ,则会得到“模型角色:(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编写。

Source: https://habr.com/ru/post/zh-CN417137/


All Articles