【问题标题】:How to conditionally require form inputs in angular 4?如何有条件地要求 Angular 4 中的表单输入?
【发布时间】:2018-01-11 21:56:59
【问题描述】:

我正在使用模板驱动的表单来添加任务,并且有 2 个类型为 number 的输入字段用于估计完成任务的分钟数,

  • 一个字段用于估计小时数和
  • 另一个是完成任务的估计分钟数

因为任务估计可以像 1hrs 这样的小时或像 1Hrs 30Mins 这样的小时和分钟完成,所以我想设置属性 required 有条件地输入。因此,必须设置 2 个输入之一,否则如果在提交表单时两个输入都为空,则会发生表单验证错误。

到目前为止我已经这样做了,但验证不起作用

<form class="add-task" (ngSubmit)="onSubmit(newtask)" #newtask="ngForm">  
    <div class="estimate-container">
        <input 
            type="number" 
            min="0" 
            max="10" 
            id="estimate_hrs" 
            ngModel 
            name="estimate_hrs"
            mdInput 
            [required]="!estimateMins.valid" 
            placeholder="Estimated Hours" 
            #estimateHrs="ngModel"
        >
        <div class="error-msg" *ngIf="!estimateHrs.valid && !estimateMins.valid">
            Please enter estimated hours 
        </div>
        <input 
            type="number" 
            min="0" 
            max="60" 
            id="estimate_min" 
            ngModel 
            name="estimate_min" 
            mdInput 
            [required]="!estimateHrs.valid" 
            placeholder="Estimated Minutes" 
            #estimateMins="ngModel"
        >
        <div class="error-msg" *ngIf="!estimateMins.valid && !estimateHrs.valid">
            Please enter estimated minutes
        </div>   
    </div>
    <button type='submit' [disabled]="!newtask.valid" >Submit</button>
</form>

【问题讨论】:

    标签: forms angular validation


    【解决方案1】:

    尝试改用 [attr.required]。

       <input 
            type="number" 
            min="0" 
            max="10" 
            id="estimate_hrs" 
            ngModel 
            name="estimate_hrs"
            mdInput 
            [attr.required]="!estimateMins.valid" 
            placeholder="Estimated Hours" 
            #estimateHrs="ngModel"
        >
    

    【讨论】:

    • 你能看看这个link
    • OP 说这不起作用,因此我认为他们可以尝试替代语法..,
    • 你通过链接了吗?,这是一个问题。有没有办法在模板驱动的表单中解决它?
    • 感谢您抽出宝贵时间回答这个问题,但它没有奏效,所以我唯一的选择是实现反应式表单吗?。
    • 我刚刚在这里做了一个 plunker,基本语法似乎工作正常:plnkr.co/edit/QAqeBYrg19dXcqbubVZ8?p=preview 所以我认为您的问题可能出在其他地方(不是必需的属性)或您绑定的内容。跨度>
    【解决方案2】:

    您需要将!estimateMins.valid 放在单引号中,例如:

    [required]="'!estimateMins.valid'"[required]="'!estimateHrs.valid'"

    看到这个plunkr

    【讨论】:

    • 最新版本的 angular(可能还有一些更早的版本)在语句中不需要单引号。因此,[required]="!estimateMins.valid" 将起作用。
    【解决方案3】:

    我花了一些时间来尝试这个,因为基本语法应该可以工作。我最初做了一个简单的 plunker 只是为了测试语法,并且语法确实按定义工作。

    在扩展 plunker 以更紧密地匹配 OP 的代码后:https://plnkr.co/edit/QAqeBYrg19dXcqbubVZ8?p=preview

    <Links to plunker must be accompanied by code>
    

    很明显,这不是语法错误。而是逻辑错误。

    当表单第一次出现时,两个控件都是有效的,所以它们都没有 required 属性。那么两者都不是必需的,而且它似乎不起作用。

    有几种可能的方法来解决这个问题。一种是构建一个执行跨字段验证的自定义验证器。

    【讨论】:

    • 感谢您的宝贵时间,后来我将其更改为反应形式,并为不同的场景制作了一系列自定义验证器,例如检查表单控件的最小最大值并据此显示错误跨度>
    【解决方案4】:

    这是我的 Angular 5 工作解决方案:

    在组件中:

    @Input()
    required: boolean;
    

    在输入(或选择)元素的模板中:

    [required]="required"
    

    在选择器上:

    [required]="true"
    

    像@DeborahK 一样双重检查,不需要单引号:-)

    【讨论】:

    • 通过添加单引号对我有用,否则它不起作用
    【解决方案5】:

    在 angular2 或更高版本中,您可以将ngNativeValidate 指令用于template driven 形式。还有object 保留并将数据(虽然这是你个人的选择,但我喜欢这种方式)发送到 api。

    <form class="add-task" #newtask="ngForm" ngNativeValidate (ngSubmit)="onSubmit()">  
    
        <div class="estimate-container">
            <input 
                type="number" 
                min="0" 
                max="10" 
                id="estimate_hrs" 
                name="estimate_hrs"
                mdInput 
                [required]="!taskModel.estimateMins" 
                placeholder="Estimated Hours" 
                [(ngModel)]="taskModel.estimateHrs">
    
            <div class="error-msg" *ngIf="!taskModel.estimateHrs && !taskModel.estimateMins">
                Please enter estimated hours 
            </div>
            <input 
                type="number" 
                min="0" 
                max="60" 
                id="estimate_min" 
                name="estimate_min" 
                mdInput 
                [required]="!taskModel.estimateHrs" 
                placeholder="Estimated Minutes" 
                [(ngModel)]="taskModel.estimateMins">
    
            <div class="error-msg" *ngIf="!taskModel.estimateMins && !taskModel.estimateHrs">
                Please enter estimated minutes
            </div>   
        </div>
        <button type='submit' [disabled]="!newtask.valid" [isFormValid]="!newtask.valid">Submit</button>
    </form>
    

    .ts 文件中

    taskModel: any;
    
    onSubmit(){
        
        console.log(this.taskModel) // this object has all data.
    }
    

    你也可以用AngularJS (version 1.x)实现同样的效果

    <form id="form" name="form" class="add-task" ng-init="taskModel={}">
    
        <div class="estimate-container">
            <input 
                type="number" 
                min="0" 
                max="10" 
                id="estimate_hrs" 
                name="estimate_hrs"
                mdInput 
                ng-required="!taskModel.estimateMins" 
                placeholder="Estimated Hours" 
                ng-model="taskModel.estimateHrs">
    
            <div class="error-msg" ng-if="!taskModel.estimateHrs && !taskModel.estimateMins">
                Please enter estimated hours 
            </div>
            <input 
                type="number" 
                min="0" 
                max="60" 
                id="estimate_min" 
                name="estimate_min" 
                mdInput 
                ng-required="!taskModel.estimateHrs" 
                placeholder="Estimated Minutes" 
                ng-model="taskModel.estimateMins">
    
            <div class="error-msg" ng-if="!taskModel.estimateMins && !taskModel.estimateHrs">
                Please enter estimated minutes
            </div>   
        </div>
        <button ng-disabled="form.$valid" ng-click="form.$valid && onSubmit()" >Submit</button>
    </form>
    

    希望对你有帮助!

    【讨论】:

      【解决方案6】:

      您可以使用[required]=boolean

      【讨论】:

        猜你喜欢
        • 2012-11-08
        • 1970-01-01
        • 2013-01-28
        • 2012-06-10
        • 1970-01-01
        • 2020-02-25
        • 2019-12-07
        • 2010-11-24
        • 1970-01-01
        相关资源
        最近更新 更多