如何实现基于ng-bootstrap模态框的Angular 5模板驱动表单以创建和编辑关闭问题?
Alright, let’s break down how to finish and optimize your Angular 5 template-driven form (with ng-bootstrap modals) for creating and editing board closure issues. Based on the code snippet you shared, here’s actionable guidance to polish this implementation:
Your current input only handles the editMode case—let’s tie it properly to both modes with two-way binding, and add validation hooks:
- For add mode: Bind the input to a component property (e.g.,
newBoardName) so you can capture the user’s input. - For edit mode: Bind directly to the existing
boardobject’s name property, but pass a copy of the board to the modal first (to avoid mutating the original until the user confirms changes).
Here’s the updated input section:
<div class="form-group"> <label for="boardName">Board name</label> <input type="text" class="form-control" id="boardName" name="boardName" [(ngModel)]="editMode ? board.name : newBoardName" required minlength="3" #boardName="ngModel" > <!-- Validation error messages --> <div *ngIf="boardName.invalid && (boardName.dirty || boardName.touched)" class="text-danger"> <div *ngIf="boardName.errors.required">Board name is required.</div> <div *ngIf="boardName.errors.minlength"> Board name must be at least {{ boardName.errors.minlength.requiredLength }} characters long. </div> </div> </div>
In your component, declare the necessary properties:
editMode = false; board: Board; // Assume Board is your interface/type newBoardName = ''; existingBoards: Board[]; // For duplicate checks later
Let’s make the modal’s user experience clearer, and ensure the form submits cleanly:
- Add a Cancel button alongside the submit button to give users an explicit way to exit without saving:
<div class="modal-footer"> <button type="button" class="btn btn-secondary" (click)="activeModal.dismiss('User canceled')">Cancel</button> <button type="submit" class="btn btn-primary" [disabled]="newBoard.invalid || isSubmitting" aria-label="{{ editMode ? 'Update board' : 'Create new board' }}" > <span *ngIf="isSubmitting" class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> {{ isSubmitting ? (editMode ? 'Updating...' : 'Creating...') : (editMode ? 'Update Board' : 'Create Board') }} </button> </div>
- Update your submission methods to handle loading states and close the modal only after successful action:
isSubmitting = false; addBoard() { this.isSubmitting = true; // Replace with your actual API/service call this.boardService.createBoard({ name: this.newBoardName }).subscribe({ next: () => { this.activeModal.close('Board created successfully'); // Emit event to parent component to refresh the board list this.boardCreated.emit(); }, error: () => { this.isSubmitting = false; // Handle error (e.g., show toast message) } }); } editBoard() { this.isSubmitting = true; this.boardService.updateBoard(this.board).subscribe({ next: () => { this.activeModal.close('Board updated successfully'); this.boardUpdated.emit(this.board); }, error: () => { this.isSubmitting = false; // Handle error } }); }
Prevent users from creating duplicate board names with a custom validator:
First, add the validator function to your component:
checkDuplicateName(control: NgModel): { [key: string]: boolean } | null { // Skip check if we're in edit mode (since we're updating an existing board) if (this.editMode) return null; const nameExists = this.existingBoards.some( b => b.name.toLowerCase() === control.value?.toLowerCase() ); return nameExists ? { duplicateName: true } : null; }
Then attach it to your input:
<input ... [validator]="checkDuplicateName" > <!-- Add duplicate name error message --> <div *ngIf="boardName.hasError('duplicateName')" class="text-danger"> This board name already exists. </div>
When opening the modal for editing, pass a copy of the board object to avoid mutating the original until the user confirms:
In your parent component (where you open the modal):
openEditModal(board: Board) { const modalRef = this.modalService.open(BoardModalComponent); modalRef.componentInstance.editMode = true; modalRef.componentInstance.board = { ...board }; // Create a shallow copy modalRef.componentInstance.existingBoards = this.boards; }
This way, if the user cancels the edit, the original board data remains unchanged.
- Add
aria-describedbyto link labels to their error messages for screen readers:
<label for="boardName" id="boardNameLabel">Board name</label> <input ... aria-describedby="boardNameError" > <div id="boardNameError" *ngIf="boardName.invalid && (boardName.dirty || boardName.touched)" class="text-danger"> <!-- Error messages here --> </div>
- Keep the
novalidateattribute on your form (you already have this!) to disable default HTML validation, since we’re using Angular’s validation system.
内容的提问来源于stack exchange,提问作者Andre1991

