select每选择一个option选项减少对应的option实现方法
作者:吴季分
这篇文章主要为大家介绍了select每选择一个option选项减少对应的option实现方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
引言
对人员投票进行排名的场景中,会有select框让用户选择每个名次对应的人员,该select框需要实现每选择一个option(人员)选项中将减少对应的option(人员)。
效果浏览
想法
对表单的值变化进行订阅,将已选中的人放入新数组中,对数组进行遍历,根据id将所有选中的人过滤掉。
实现步骤
根据人员数量生成对应数量的select框
formGroup = new FormGroup({}); constructor(private fb: FormBuilder) { } createForm() : void{ for(let i = 1; i <= this.members.length; i++) { this.formGroup.addControl(`${i}`, this.fb.control(null)) } }
FormBuilder 提供了一个语法糖,以简化 FormControl、FormGroup 或 FormArray 实例的创建过程。 它会减少构建复杂表单时所需的样板代码的数量。
class FormBuilder { group(controlsConfig: {...}, extra: {...}): FormGroup control(formState: any, validator?: ValidatorFn | ValidatorFn[] | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormControl array(controlsConfig: any[], validator?: ValidatorFn | ValidatorFn[] | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormArray }
group: 构建一个新的 FormGroup 实例。
this.form = this.fb.group({ name: '123', age: 9, gender: false })
control(): 构建一个新的 FormControl 实例。
this.formGroup.addControl(`${i}`, this.fb.control(null))
array(): 构造一个新的 FormArray 实例。
form: FormArray = new FormArray<any>([ this.fb.control(null), this.fb.control(null), this.fb.control(null), ]);
数据绑定
<app-member-select [members]="users" formControlName="{{ i + 1 }}"></app-member-select>
MemberSelectComponent组件:
import {Component, forwardRef, Input, OnInit, Output} from '@angular/core'; import {ControlValueAccessor, FormControl, NG_VALUE_ACCESSOR} from "@angular/forms"; import {User} from "../../../entity/user"; import {BehaviorSubject} from "rxjs"; import {UserService} from "../../../service/user.service"; import {EventEmitter} from "protractor"; import {Assert} from "@yunzhi/utils"; @Component({ selector: 'app-member-select', templateUrl: './member-select.component.html', styleUrls: ['./member-select.component.css'], providers: [{ provide: NG_VALUE_ACCESSOR, multi: true, useExisting: forwardRef(() => MemberSelectComponent) }] }) export class MemberSelectComponent implements OnInit, ControlValueAccessor { @Input() members: User[] = []; memberSelect = new FormControl<User>(null); ngOnInit(): void { } /** * 子组件需要向父组件弹值时,直接调用参数的fn方法 * 相当于@Ouput() * @param fn 此类型取决于当前组件的弹出值类型 */ registerOnChange(fn: (user: User) => void): void { this.memberSelect.valueChanges.subscribe((data => { fn(data); })); } registerOnTouched(fn: any): void { } /** * 将FormControl中的值通过此方法写入 * FormControl的值每变换一次,该方法被重新执行一次 * 相当于@Input set XXX */ writeValue(user: User): void { if (user === null) { return; } this.memberSelect.setValue(user); } /** * 比较函数,标识用哪个字段来比较两个对象是否为同一个对象 * @param t1 源 * @param t2 目标 */ compareFn(t1: { id: number }, t2: { id: number }): boolean { return t1 && t2 ? t1.id === t2.id : t1 === t2; } }
获取已选择的人员进行过滤
this.formGroup.valueChanges.subscribe(v => { let idsToFilter: number[] = []; // 遍历 v 的属性,如果属性值不为 null,则将其 id 加入数组 for (const key in v) { if (v[key] !== null && v[key].id !== undefined) { idsToFilter.push(v[key].id); } } // 过滤掉与 idsToFilter 中任何一个 id 相同的元素 this.users = this.members.filter(member => !idsToFilter.includes(member.id)); })
目标效果就达成,希望这篇文章对你有所帮助,更多关于select option选项减少的资料请关注脚本之家其它相关文章!