typescript - Angular 2: Kontrollera om inmatning i reaktivt formulär är tom, ange standardvärde om ingen inmatning ges
Redigera 2: Förbättrade den delvisa lösningen och nu är det en komplett lösning. Yay!
Redigera: Hittade en nästan komplett lösning. Den fungerar, men inte riktigt på det sätt jag vill.
- Det sätter ett standardvärde från det ögonblick formuläret laddas. (inte idealiskt)
- Det returnerar inte längre null om inmatningen är tom eller borttagen (returnerar istället en tom sträng)
Lösningen läggs upp efter texten nedan.
Jag är en ny student i Angular och jag gör en enkel CRUD-app för att förstå hur språket fungerar. För närvarande lär jag mig hur man gör formulärvalideringar.
Som nämnts i titeln vill jag ha en valideringsmetod som kontrollerar om inmatningen är tom, och om den är det, ange ett standardvärde. Jag letar efter ett rent och enkelt sätt att göra detta. För närvarande är här min kod.
delvis post.component.html (ursäkta de flera raderna för <input>-elementet; jag tycker det är lättare att läsa på det här sättet)
<modal #modal>
<form novalidate (ngSubmit)="onSubmit(postForm)" [formGroup]="postForm">
<modal-header [show-close]="true">
<h4 class="modal-title">{{modalTitle}}</h4>
</modal-header>
<modal-body>
<div class="form-group">
<div>
<span>Post Title</span>
<input [(ngModel)]="TitleText"
type="text" class="form-control"
placeholder="Post Title"
formControlName="PostTitle">
<div class="error"
*ngIf="postForm.get('PostTitle').hasError('required') && postForm.get('PostTitle').touched">
Title is required
</div>
<div class="error"
*ngIf="postForm.get('PostTitle').hasError('minlength') && postForm.get('PostTitle').touched">
Minimum title length is three (3) characters
</div>
</div>
<div>
<span>Post Slug</span>
<input [ngModel]="TitleText | slugify"
type="text"
class="form-control"
placeholder="Post Slug"
formControlName="PostSlug">
<div class="error"
*ngIf="postForm.get('PostSlug').hasError('pattern') && postForm.get('PostSlug').dirty">
URL slug must not contain spaces, special characters or capitalization
</div>
</div>
<div>
<span>Post Content</span>
<textarea class="form-control"
placeholder="Post Content"
formControlName="PostContent">
</textarea>
</div>
<div>
<span>Post Author</span>
<input type="text"
class="form-control"
placeholder="Post Author"
formControlName="PostAuthor">
</div>
</div>
</modal-body>
<modal-footer>
<div>
<a class="btn btn-default" (click)="modal.dismiss()">Cancel</a>
<button type="submit"
[disabled]="postForm.invalid"
class="btn btn-primary">
{{modalBtnTitle}}
</button>
</div>
</modal-footer>
</form>
</modal>
delvis post.component.ts
ngOnInit(): void {
this.postForm = this.fb.group({
PostId: [''],
PostTitle: [
'',
[
Validators.required,
Validators.minLength(3)
]
],
PostSlug: [
'',
[
Validators.required,
Validators.pattern('^[a-z0-9-]+$')
]
],
PostContent: [''],
PostAuthor: ['']
});
this.LoadPosts();
}
Jag skulle vilja att ett standardvärde skickas om fälten PostContent och PostAuthor lämnas tomma. Ett sätt som jag tänkte skulle kunna fungera var att ha ett standardvärde i mallen på följande sätt:
<textarea class="form-control"
placeholder="Post Content"
formControlName="PostContent"
value="Not Set">
Men detta fungerar inte och felsökning visar att null fortfarande returneras:
Det är lika bra, eftersom den lösningen ändå skulle ha orsakat ett problem om någon bestämde sig för att skriva något och sedan radera det.
Som referens, här är hela post.component.ts:
import { Component, OnInit, ViewChild, Pipe } from '@angular/core';
import { PostService } from '../Services/post.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import { IPost } from '../Models/post';
import { DBOperation } from '../Shared/enum';
import { Observable } from 'rxjs/Rx';
import { Global } from '../Shared/global';
@Component({
templateUrl: '/app/Components/post.component.html'
})
export class PostComponent implements OnInit {
@ViewChild('modal') modal: ModalComponent;
posts: IPost[];
post: IPost;
msg: string;
indLoading: boolean = false;
postForm: FormGroup;
dbops: DBOperation;
modalTitle: string;
modalBtnTitle: string;
constructor(private fb: FormBuilder, private _postService: PostService) { }
ngOnInit(): void {
this.postForm = this.fb.group({
PostId: [''],
PostTitle: [
'',
[
Validators.required,
Validators.minLength(3)
]
],
PostSlug: [
'',
[
Validators.required,
Validators.pattern('^[a-z0-9-]+$')
]
],
PostContent: [''],
PostAuthor: ['']
});
this.LoadPosts();
}
LoadPosts(): void {
this.indLoading = true;
this._postService.get(Global.BASE_POST_ENDPOINT)
.subscribe(posts => { this.posts = posts; this.indLoading = false; },
error => this.msg = <any>error);
}
addPost() {
this.dbops = DBOperation.create;
this.SetControlsState(true);
this.modalTitle = "Add New Post";
this.modalBtnTitle = "Add";
this.postForm.reset();
this.modal.open();
}
editPost(id: number) {
this.dbops = DBOperation.update;
this.SetControlsState(true);
this.modalTitle = "Edit Post";
this.modalBtnTitle = "Update";
this.post = this.posts.filter(x => x.PostId == id)[0];
this.postForm.setValue(this.post);
this.modal.open();
}
deletePost(id: number) {
this.dbops = DBOperation.delete;
this.SetControlsState(false);
this.modalTitle = "Confirm Post Deletion?";
this.modalBtnTitle = "Delete";
this.post = this.posts.filter(x => x.PostId == id)[0];
this.postForm.setValue(this.post);
this.modal.open();
}
SetControlsState(isEnable: boolean) {
isEnable ? this.postForm.enable() : this.postForm.disable();
}
onSubmit(formData: any) {
this.msg = "";
switch (this.dbops) {
case DBOperation.create:
this._postService.post(Global.BASE_POST_ENDPOINT, formData._value).subscribe(
data => {
if (data == 1) //Success
{
this.msg = "Post successfully added.";
this.LoadPosts();
}
else {
this.msg = "There is an issue with creating the post, please contact the system administrator!"
}
this.modal.dismiss();
},
error => {
this.msg = error;
}
);
break;
case DBOperation.update:
this._postService.put(Global.BASE_POST_ENDPOINT, formData._value.PostId, formData._value).subscribe(
data => {
if (data == 1) //Success
{
this.msg = "Post successfully updated.";
this.LoadPosts();
}
else {
this.msg = "There is an issue with updating the post, please contact the system administrator!"
}
this.modal.dismiss();
},
error => {
this.msg = error;
}
);
break;
case DBOperation.delete:
this._postService.delete(Global.BASE_POST_ENDPOINT, formData._value.PostId).subscribe(
data => {
if (data == 1) //Success
{
this.msg = "Post successfully deleted.";
this.LoadPosts();
}
else {
this.msg = "There is an issue with deleting the post, please contact the system administrator!"
}
this.modal.dismiss();
},
error => {
this.msg = error;
}
);
break;
}
}
}
Ska jag titta på att lägga till Null-kontrollen i onSubmit-metoden (eller är det en funktion?) istället?
Potentiell lösning, behöver förbättras
Så i delen addPost() av post.component.ts ovan, lade jag till två rader:
addPost() {
this.dbops = DBOperation.create;
this.SetControlsState(true);
this.modalTitle = "Add New Post";
this.modalBtnTitle = "Add";
this.postForm.reset();
this.modal.open();
this.postForm.controls['PostContent'].setValue('not set'); //this here is the magic
this.postForm.controls['PostAuthor'].setValue('not credited'); // and this too
}
Detta sätter i princip värdet från det ögonblick modalfönstret för att ange en ny post laddas. Värdet kan tas bort från inmatningen och när det händer ersätts det med en tom sträng. Jag vet inte var detta värde med tom sträng kommer ifrån.
Svar #1
Oavsett vilken 'form' (reaktiv eller mallbaserad) du använder, om allt du vill är att ha ett standardvärde när inmatningen blir tom, kan du använda ngModelChange-händelsen. Du måste dock importera FormsModule till din modul (där du använder denna komponent som har denna mall som sin vy) för att det ska fungera. Använd ngModel för att skicka det initiala värdet, om du har något.
komponent
// define the type
postAuthorInitValue: string;
postAuthorDefaultValue = 'DEFAULT VALUE';
// or initialize it with a value, assign the right type (here I used string type)
// postAuthorInitValue = 'Abc Xyz';
postAuthorChanged(newVal: string): void {
if (newVal) {
this.postAuthorInitValue = newVal;
} else if (newVal === '') {
// here is where we put the default value when the 'newVal' is empty string
this.postAuthorInitValue = this.postAuthorDefaultValue;
} else {
this.postAuthorInitValue = newVal;
}
}
mall
<input type="text"
[ngModel]="postAuthorInitValue"
(ngModelChange)="postAuthorChanged($event)"
class="form-control"
placeholder="Post Author"
formControlName="PostAuthor">
Ett annat alternativ skulle vara att använda en anpassad direktiv som kan placeras på varje <input type="text">-element som läser dess värde och ett standardvärde och sätter standardvärdet till elementet när fältet blir tomt.
Hoppas det hjälper.
Svar #2
REDIGERA: Okej, trodde detta skulle vara enklare, men jag hade fel.
Du skulle antagligen behöva något som en funktion checkme() i din TS-fil som kallas när din skicka-knapp trycks, <button (click)="checkme()">Skicka</button> som kontrollerar:
checkme() {
if (TitleText===null) {
TitleText = 'default value';
}
}
eller något.
Ovidkommmande nedan men kan vara användbart
Om du har:
<input [(ngModel)]="TitleText">
Sedan springa
{{TitleText || 'placeholder'}}kommer att ge dig strängen 'placeholder' om inmatningsrutan är tom (TitleText är null).
Det skulle vara samma princip med sifferringångar där du skulle skriva:
<input [(ngModel)]="mynumber">
och skrivande
{{mynumber || 0}}
att få 0 som en platshållare istället för NaN
