如何在Angular 4中有条件地要求表单输入?

25

我正在使用基于模板的表单来添加任务,其中有2个类型为数字的输入字段以估计完成任务所需的时间(分钟):

  • 一个字段用于估计小时数,
  • 另一个字段用于估计分钟数。

由于任务估计可以用小时表示,例如1小时,也可以用小时和分钟表示,例如1小时30分钟,因此我想有条件地将属性required设置为输入。 因此,无论哪个输入都必须设置,如果在提交表单时两个输入都为空,则会出现表单验证错误。

到目前为止,我已经做到了这一点,但是验证不起作用。

<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>
6个回答

17

尝试使用[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"
    >

你能看一下这个链接吗? - k11k2
OP说那个不起作用,因此我想他们可以尝试替代语法.., - DeborahK
你有没有查看链接?这是一个问题。在模板驱动表单中有解决方法吗? - k11k2
谢谢您抽出时间回答这个问题,但是它并没有起作用,那么我的唯一选择是实现响应式表单吗? - R.K
你尝试过将代码简化到基础部分以确保问题出在哪里吗?尝试去掉所有其他属性,看看是否有任何变化。另外,你能否创建一个演示该问题的 Plunker? - DeborahK
1
我刚刚在这里做了一个 Plunker,基本语法似乎运行良好:https://plnkr.co/edit/QAqeBYrg19dXcqbubVZ8?p=preview。所以我认为你的问题可能出在其他地方(而不是所需属性)或者你绑定的内容上。 - DeborahK

16

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

在组件中:

@Input()
required: boolean;

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

[required]="required"
在选择器上:
[required]="true"

就像@DeborahK所说的那样,不需要单引号:-)


'通过添加单引号,它对我有效,否则它不起作用。' - Vaibhav Shaha

9

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

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

请参见此plunkr


最近版本的Angular(也许还有一些早期版本)不需要在语句中使用单引号。因此,[required] =“!estimateMins.valid”将起作用。 - Marin

3
您可以使用 [required]=boolean

2
我花了一些时间尝试这个,因为基本语法应该是可以工作的。我最初做了一个简单的plunker来测试语法,语法确实如定义的那样工作。
在扩展plunker以更接近OP的代码后:https://plnkr.co/edit/QAqeBYrg19dXcqbubVZ8?p=preview
<Links to plunker must be accompanied by code>

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

当表单首次出现时,两个控件都是有效的,因此它们都没有必需属性。因此,它们都不是必需的,看起来好像无法正常工作。

有几种可能的解决方法。其中一种是构建一个自定义验证器来进行跨字段验证。


感谢您的时间,后来我将其更改为响应式表单,并为不同情况制作了自定义验证器数组,例如检查表单控件的最小值和最大值,并根据此显示错误。 - R.K

0
在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(版本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>

希望对你有所帮助!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接