角度2:检查被动形式的输入是否为空,如果没有给出输入,则输入默认值

时间:2017-09-27 21:20:03

标签: angular typescript

编辑2:改进了部分解决方案,现在它是一个完整的解决方案。耶!

编辑:找到一个几乎完整的解决方案。它有效,但不是我想要的方式。

  1. 从表单加载的那一刻起设置默认值。 (不理想)
  2. 如果输入为空/删除(返回空字符串)
  3. ,则不再返回null

    解决方案发布在以下文字之后。

    我是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();
        }
    

    如果PostContentPostAuthor字段为空,我希望传递默认值。我认为可行的一种方法是在模板中使用默认值,如下所示:

    <textarea class="form-control"
        placeholder="Post Content"
        formControlName="PostContent"
        value="Not Set">
    

    但是这不起作用,调试它表明仍然返回null:

    It's not passing the value hard-coded(ewww...) in the value attribute

    同样,因为如果有人决定输入内容然后将其删除,那么该解决方案无论如何都会引起问题。

    供参考,这是整个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

    这基本上设置了从加载模式框进入新条目的那一刻起的值。可以从输入中删除该值,当发生这种情况时,它将替换为空字符串。我不知道这个空字符串值来自何处。

3 个答案:

答案 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