编辑2:改进了部分解决方案,现在它是一个完整的解决方案。耶!
编辑:找到一个几乎完整的解决方案。它有效,但不是我想要的方式。
解决方案发布在以下文字之后。
我是Angular的新生,我正在制作一个简单的CRUD应用程序,以了解该语言的工作原理。目前,我正在学习如何进行表单验证。
正如标题中所提到的,我希望有一个验证方法来检查输入是否为空,然后是否输入默认值。我正在寻找一种干净简单的方法来做到这一点。目前这是我的代码。
partial post.component.html
(对于<input>
元素的多行感到抱歉;我觉得这种方式更容易阅读)
<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>
partial 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();
}
如果PostContent
和PostAuthor
字段为空,我希望传递默认值。我认为可行的一种方法是在模板中使用默认值,如下所示:
<textarea class="form-control"
placeholder="Post Content"
formControlName="PostContent"
value="Not Set">
但是这不起作用,调试它表明仍然返回null:
同样,因为如果有人决定输入内容然后将其删除,那么该解决方案无论如何都会引起问题。
供参考,这是整个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;
}
}
}
我应该考虑在onSubmit
方法中添加Null检查(或者它是否正常?)?
潜在的解决方案,需要改进
所以在上面addPost()
的{{1}}部分,我添加了两行:
post.component.ts
这基本上设置了从加载模式框进入新条目的那一刻起的值。可以从输入中删除该值,当发生这种情况时,它将替换为空字符串。我不知道这个空字符串值来自何处。
答案 0 :(得分:2)
无论您使用什么'形式'(被动或模板驱动),如果您想要的只是在输入变空时具有默认值,您可以使用ngModelChange
事件。必须将FormsModule
导入您的模块(使用此模块作为其视图的组件)才能使其正常工作。如果您有任何原因,请使用ngModel
传递初始值。
成分</ P>
// 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;
}
}
模板
<input type="text"
[ngModel]="postAuthorInitValue"
(ngModelChange)="postAuthorChanged($event)"
class="form-control"
placeholder="Post Author"
formControlName="PostAuthor">
另一种选择是使用一个自定义指令,该指令可以放在读取其值和默认值的每个<input type="text">
元素上,并在字段变空时将默认值设置为该元素。
希望它有所帮助。
答案 1 :(得分:1)
好的,所以我找到了一个优雅的解决方案。基本上,我需要在加载表单时设置初始值。为此,我添加了使用setValue方法的窗体控件。
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
}
这样做似乎以笨重的方式解决了这个问题。该值已在相关输入字段中预先填充,如果已删除,则该值将变为空字符串。这不太理想。
所以我把它翻过来并这样做:
this.postForm.controls['PostContent'].setValue('');
this.postForm.controls['PostAuthor'].setValue('');
这里我将值设置为空字符串。它不为空,但输入字段未预先填充,我的placeholder
值仍然可见。优秀。但那空字符串呢?
我们在将数据传递给执行HttpPost的服务之前处理它。
onSubmit(formData: any) {
this.msg = "";
if (formData._value.PostContent == "")
{
this.postForm.controls['PostContent'].setValue('not set');
}
if (formData._value.PostAuthor == "")
{
this.postForm.controls['PostAuthor'].setValue('not credited');
}
. . .
如果为这些特定键传递的值是空字符串,则会将该值设置为默认值。
我认为这是解决这个问题的好方法。它很干净,虽然我不确定它是否可以这样做,理论上将所有默认值放在键值对数组中并以这种方式访问它并不困难。
答案 2 :(得分:0)
编辑:好的以为这会更容易,但我错了。
您的TS文件中可能需要类似函数checkme()
的函数,当您调用提交按钮时调用该函数,<button (click)="checkme()">Submit</button>
检查:
checkme() {
if (TitleText===null) {
TitleText = 'default value';
}
}
或其他什么。
以下不相关,但可能有用
如果你有:
<input [(ngModel)]="TitleText">
然后运行
{{TitleText || 'placeholder'}}
会为您提供字符串&#39;占位符&#39;如果输入框为空(TitleText为空)。
与您输入的数字输入相同的原则是:
<input [(ngModel)]="mynumber">
并撰写
{{mynumber || 0}}
将0作为占位符而不是NaN