select每選擇一個(gè)option選項(xiàng)減少對(duì)應(yīng)的option實(shí)現(xiàn)方法
引言
對(duì)人員投票進(jìn)行排名的場(chǎng)景中,會(huì)有select框讓用戶(hù)選擇每個(gè)名次對(duì)應(yīng)的人員,該select框需要實(shí)現(xiàn)每選擇一個(gè)option(人員)選項(xiàng)中將減少對(duì)應(yīng)的option(人員)。
效果瀏覽
想法
對(duì)表單的值變化進(jìn)行訂閱,將已選中的人放入新數(shù)組中,對(duì)數(shù)組進(jìn)行遍歷,根據(jù)id將所有選中的人過(guò)濾掉。
實(shí)現(xiàn)步驟
根據(jù)人員數(shù)量生成對(duì)應(yīng)數(shù)量的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 提供了一個(gè)語(yǔ)法糖,以簡(jiǎn)化 FormControl、FormGroup 或 FormArray 實(shí)例的創(chuàng)建過(guò)程。 它會(huì)減少構(gòu)建復(fù)雜表單時(shí)所需的樣板代碼的數(shù)量。
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: 構(gòu)建一個(gè)新的 FormGroup 實(shí)例。
this.form = this.fb.group({ name: '123', age: 9, gender: false })
control(): 構(gòu)建一個(gè)新的 FormControl 實(shí)例。
this.formGroup.addControl(`${i}`, this.fb.control(null))
array(): 構(gòu)造一個(gè)新的 FormArray 實(shí)例。
form: FormArray = new FormArray<any>([ this.fb.control(null), this.fb.control(null), this.fb.control(null), ]);
數(shù)據(jù)綁定
<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 { } /** * 子組件需要向父組件彈值時(shí),直接調(diào)用參數(shù)的fn方法 * 相當(dāng)于@Ouput() * @param fn 此類(lèi)型取決于當(dāng)前組件的彈出值類(lèi)型 */ registerOnChange(fn: (user: User) => void): void { this.memberSelect.valueChanges.subscribe((data => { fn(data); })); } registerOnTouched(fn: any): void { } /** * 將FormControl中的值通過(guò)此方法寫(xiě)入 * FormControl的值每變換一次,該方法被重新執(zhí)行一次 * 相當(dāng)于@Input set XXX */ writeValue(user: User): void { if (user === null) { return; } this.memberSelect.setValue(user); } /** * 比較函數(shù),標(biāo)識(shí)用哪個(gè)字段來(lái)比較兩個(gè)對(duì)象是否為同一個(gè)對(duì)象 * @param t1 源 * @param t2 目標(biāo) */ compareFn(t1: { id: number }, t2: { id: number }): boolean { return t1 && t2 ? t1.id === t2.id : t1 === t2; } }
獲取已選擇的人員進(jìn)行過(guò)濾
this.formGroup.valueChanges.subscribe(v => { let idsToFilter: number[] = []; // 遍歷 v 的屬性,如果屬性值不為 null,則將其 id 加入數(shù)組 for (const key in v) { if (v[key] !== null && v[key].id !== undefined) { idsToFilter.push(v[key].id); } } // 過(guò)濾掉與 idsToFilter 中任何一個(gè) id 相同的元素 this.users = this.members.filter(member => !idsToFilter.includes(member.id)); })
目標(biāo)效果就達(dá)成,希望這篇文章對(duì)你有所幫助,更多關(guān)于select option選項(xiàng)減少的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
再談Javascript中的基本類(lèi)型和引用類(lèi)型(推薦)
這篇文章主要介紹了Javascript中的基本類(lèi)型和引用類(lèi)型的相關(guān)資料,包括基本類(lèi)型和引用類(lèi)型的概念及區(qū)別,數(shù)據(jù)類(lèi)型檢測(cè)給大家詳細(xì)介紹了js基本類(lèi)型和引用類(lèi)型,非常不錯(cuò),需要的朋友可以參考下2016-07-07解決layui動(dòng)態(tài)添加的元素click等事件觸發(fā)不了的問(wèn)題
今天小編就為大家分享一篇解決layui動(dòng)態(tài)添加的元素click等事件觸發(fā)不了的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-09-09JS switch判斷 三目運(yùn)算 while 及 屬性操作代碼
這篇文章主要介紹了JS switch判斷 三目運(yùn)算 while 及 屬性操作代碼,需要的朋友可以參考下2017-09-09原生javascript實(shí)現(xiàn)獲取指定元素下所有后代元素的方法
這篇文章主要介紹了原生javascript實(shí)現(xiàn)獲取指定元素下所有后代元素的方法,在進(jìn)行web程序設(shè)計(jì)時(shí)是非常實(shí)用的技巧,需要的朋友可以參考下2014-10-10元素的內(nèi)聯(lián)事件處理函數(shù)的特殊作用域在各瀏覽器中存在差異
在一個(gè)元素的屬性中綁定事件,實(shí)際上就創(chuàng)建了一個(gè)內(nèi)聯(lián)事件處理函數(shù)(如<h1 onclick="alert(this);"...>...</h1>),內(nèi)聯(lián)事件處理函數(shù)有其特殊的作用域鏈,并且各瀏覽器的實(shí)現(xiàn)細(xì)節(jié)也有差異。2011-01-01JavaScript獲取GridView中用戶(hù)點(diǎn)擊控件的行號(hào),列號(hào)
GridView中的某幾列有按鈕,需要獲取用戶(hù)當(dāng)前點(diǎn)的按鈕的行號(hào)(捎帶的得到列號(hào))2009-04-04JavaScript JSON.stringify()的使用總結(jié)
JSON是一種輕量級(jí)數(shù)據(jù)格式,可以方便地表示復(fù)雜數(shù)據(jù)結(jié)構(gòu)。JSON對(duì)象有兩個(gè)方法:stringify()和parse()。在簡(jiǎn)單的情況下,這兩個(gè)方法分別可以將JavaScript序列化為JSON字符串,以及將JSON解析為原生JavaScript值。本文著重介紹JSON.stringify()的使用方法和注意事項(xiàng)。2021-05-05