Angular FormArray 索引未传递到输入文件类型更改事件中
Angular FormArray Index not getting passed into Input file type change event
我有一个 Angular ReactiveForms FormArray,它基本上呈现一个带有文件输入的扩展面板。我想传递用于选择文件的 FormArray 的 FormGroup 的索引。为此,我将索引 (bankAccountIndex) 作为附加参数传递给文件输入(更改)事件。但是,该值始终为零。如果我在标记中对值进行硬编码,那么我会在代码隐藏中获得该值,但在我传递索引变量时不会。
下面是我的代码:
<mat-accordion [togglePosition]="'before'">
<ng-container *ngFor="let bankFormGroup of bankAccountsFormArray.controls; let bankAccountIndex=index">
<ng-container [formGroupName]="bankAccountIndex">
<mat-expansion-panel>
<span>
<label for="file-upload" class="override-margin-bottom" [ngClass]="{'disabled-control': form.disabled}">
<fa-icon [icon]="faUpload" class="file-upload-icon" size="lg"></fa-icon>
</label>
<input type="file" id="file-upload" (change)="onHandleBankLogoUploadEvent($event.target.files, bankAccountIndex)"
style="display: none;" />
<input type="text" #bankLogo formControlName="bankLogoBase64Image" style="display: none;">
<img [src]="bankLogo.value" *ngIf="bankLogo.value" style="height: 30px;" />
</span>
</mat-expansion-panel>
</ng-container>
</ng-container>
</mat-accordion>
TypeScript 文件输入更改事件处理程序:
onHandleBankLogoUploadEvent(files: FileList, bankAccountIndex: number) {
...
}
我的组件 OnInit():
ngOnInit() {
this.toastrService.overlayContainer = this.toastContainer;
this.toastrService.clear();
this.initializeForm();
this.bankAccounts$ = this.firestore.collection<BankAccount>('bankAccounts')
.valueChanges({ idField: 'docId' })
.pipe(tap(result => {
this.bankAccounts = result;
this.distinctBankNames = result.map(bank => bank.bankName).filter((value, index, self) => self.indexOf(value) === index);
}));
this.bankAccounts$_subscription = this.bankAccounts$.subscribe(_ => {
this.userContext$_subscription = this.appStoreService.userContext$.subscribe(context => {
if (!!context) {
this.toastrService.clear();
this.selectedUser = context;
this.selectedUserDocId = this.selectedUser.docId;
this.initializeForm();
} else {
this.toastrService.info('Please select a specific family member.', null,
{
closeButton: true,
disableTimeOut: true,
enableHtml: false,
positionClass: 'toast-top-center',
easeTime: 100
});
}
});
});
}
initializeForm() {
this.userFormGroup = this.formBuilder.group({
isActive: [true, Validators.required],
firstName: [this.selectedUser ? this.selectedUser.firstName : '', Validators.required],
lastName: [this.selectedUser ? this.selectedUser.lastName : '', Validators.required],
gender: [this.selectedUser ? this.selectedUser.gender : null, Validators.required],
email: [this.selectedUser ? this.selectedUser.email : ''],
pan: [this.selectedUser ? this.selectedUser.pan : ''],
mobile: [this.selectedUser ? this.selectedUser.mobile : ''],
aadharId: [this.selectedUser ? this.selectedUser.aadharId : ''],
bankAccounts: this.selectedUser && this.selectedUser.bankAccountsRefs && this.selectedUser.bankAccountsRefs.length > 0 ?
this.buildBankAccountsFormArray(this.selectedUser.bankAccountsRefs) : this.formBuilder.array([]),
passports: this.selectedUser && this.selectedUser.passports && this.selectedUser.passports.length > 0 ?
this.buildPassportsFormArray(this.selectedUser.passports) : this.formBuilder.array([]),
webLogins: this.selectedUser && this.selectedUser.webLogins && this.selectedUser.webLogins.length > 0 ?
this.buildWebLoginsFormArray(this.selectedUser.webLogins) : this.formBuilder.array([]),
});
}
buildBankAccountsFormArray(bankAccountsRefs: DocumentReference[]): FormArray {
if (bankAccountsRefs && bankAccountsRefs.length > 0) {
const usersBankAccounts = this.bankAccounts.filter(acct => bankAccountsRefs.some(ref => ref.path.includes(acct.docId)));
const bankAccountFormGroups = usersBankAccounts.map(acct => this.formBuilder.group({
docId: [acct.docId],
bankName: [acct.bankName, Validators.required],
bankLogoBase64Image: [acct.bankLogoBase64Image],
accountNumber: [acct.accountNumber, Validators.required],
ifscCode: [acct.ifscCode, Validators.required],
loginUserId: [acct.loginUserId],
loginPassword: [acct.loginPassword],
transactionPassword: [acct.transactionPassword],
isActive: [acct.isActive, Validators.required],
}))
return this.formBuilder.array(bankAccountFormGroups);
}
}
您的问题是 ID。
您应该为每个输入分配唯一的 ID:
<label [for]="'file-upload-' + bankAccountIndex" class="override-margin-bottom" [ngClass]="{'disabled-control': form.disabled}">
<fa-icon [icon]="faUpload" class="file-upload-icon" size="lg"></fa-icon>
</label>
<input type="file" [id]="'file-upload-' + bankAccountIndex" (change)="onHandleBankLogoUploadEvent($event.target.files, bankAccountIndex)" style="display: none;" />
我有一个 Angular ReactiveForms FormArray,它基本上呈现一个带有文件输入的扩展面板。我想传递用于选择文件的 FormArray 的 FormGroup 的索引。为此,我将索引 (bankAccountIndex) 作为附加参数传递给文件输入(更改)事件。但是,该值始终为零。如果我在标记中对值进行硬编码,那么我会在代码隐藏中获得该值,但在我传递索引变量时不会。
下面是我的代码:
<mat-accordion [togglePosition]="'before'">
<ng-container *ngFor="let bankFormGroup of bankAccountsFormArray.controls; let bankAccountIndex=index">
<ng-container [formGroupName]="bankAccountIndex">
<mat-expansion-panel>
<span>
<label for="file-upload" class="override-margin-bottom" [ngClass]="{'disabled-control': form.disabled}">
<fa-icon [icon]="faUpload" class="file-upload-icon" size="lg"></fa-icon>
</label>
<input type="file" id="file-upload" (change)="onHandleBankLogoUploadEvent($event.target.files, bankAccountIndex)"
style="display: none;" />
<input type="text" #bankLogo formControlName="bankLogoBase64Image" style="display: none;">
<img [src]="bankLogo.value" *ngIf="bankLogo.value" style="height: 30px;" />
</span>
</mat-expansion-panel>
</ng-container>
</ng-container>
</mat-accordion>
TypeScript 文件输入更改事件处理程序:
onHandleBankLogoUploadEvent(files: FileList, bankAccountIndex: number) {
...
}
我的组件 OnInit():
ngOnInit() {
this.toastrService.overlayContainer = this.toastContainer;
this.toastrService.clear();
this.initializeForm();
this.bankAccounts$ = this.firestore.collection<BankAccount>('bankAccounts')
.valueChanges({ idField: 'docId' })
.pipe(tap(result => {
this.bankAccounts = result;
this.distinctBankNames = result.map(bank => bank.bankName).filter((value, index, self) => self.indexOf(value) === index);
}));
this.bankAccounts$_subscription = this.bankAccounts$.subscribe(_ => {
this.userContext$_subscription = this.appStoreService.userContext$.subscribe(context => {
if (!!context) {
this.toastrService.clear();
this.selectedUser = context;
this.selectedUserDocId = this.selectedUser.docId;
this.initializeForm();
} else {
this.toastrService.info('Please select a specific family member.', null,
{
closeButton: true,
disableTimeOut: true,
enableHtml: false,
positionClass: 'toast-top-center',
easeTime: 100
});
}
});
});
}
initializeForm() {
this.userFormGroup = this.formBuilder.group({
isActive: [true, Validators.required],
firstName: [this.selectedUser ? this.selectedUser.firstName : '', Validators.required],
lastName: [this.selectedUser ? this.selectedUser.lastName : '', Validators.required],
gender: [this.selectedUser ? this.selectedUser.gender : null, Validators.required],
email: [this.selectedUser ? this.selectedUser.email : ''],
pan: [this.selectedUser ? this.selectedUser.pan : ''],
mobile: [this.selectedUser ? this.selectedUser.mobile : ''],
aadharId: [this.selectedUser ? this.selectedUser.aadharId : ''],
bankAccounts: this.selectedUser && this.selectedUser.bankAccountsRefs && this.selectedUser.bankAccountsRefs.length > 0 ?
this.buildBankAccountsFormArray(this.selectedUser.bankAccountsRefs) : this.formBuilder.array([]),
passports: this.selectedUser && this.selectedUser.passports && this.selectedUser.passports.length > 0 ?
this.buildPassportsFormArray(this.selectedUser.passports) : this.formBuilder.array([]),
webLogins: this.selectedUser && this.selectedUser.webLogins && this.selectedUser.webLogins.length > 0 ?
this.buildWebLoginsFormArray(this.selectedUser.webLogins) : this.formBuilder.array([]),
});
}
buildBankAccountsFormArray(bankAccountsRefs: DocumentReference[]): FormArray {
if (bankAccountsRefs && bankAccountsRefs.length > 0) {
const usersBankAccounts = this.bankAccounts.filter(acct => bankAccountsRefs.some(ref => ref.path.includes(acct.docId)));
const bankAccountFormGroups = usersBankAccounts.map(acct => this.formBuilder.group({
docId: [acct.docId],
bankName: [acct.bankName, Validators.required],
bankLogoBase64Image: [acct.bankLogoBase64Image],
accountNumber: [acct.accountNumber, Validators.required],
ifscCode: [acct.ifscCode, Validators.required],
loginUserId: [acct.loginUserId],
loginPassword: [acct.loginPassword],
transactionPassword: [acct.transactionPassword],
isActive: [acct.isActive, Validators.required],
}))
return this.formBuilder.array(bankAccountFormGroups);
}
}
您的问题是 ID。 您应该为每个输入分配唯一的 ID:
<label [for]="'file-upload-' + bankAccountIndex" class="override-margin-bottom" [ngClass]="{'disabled-control': form.disabled}">
<fa-icon [icon]="faUpload" class="file-upload-icon" size="lg"></fa-icon>
</label>
<input type="file" [id]="'file-upload-' + bankAccountIndex" (change)="onHandleBankLogoUploadEvent($event.target.files, bankAccountIndex)" style="display: none;" />