【问题标题】:Set Required to a custom Angular2 dropdown component将必需设置为自定义 Angular2 下拉组件
【发布时间】:2017-03-31 20:13:34
【问题描述】:

我有一个输入字段很少和自定义下拉列表的表单。问题是:我可以将 my-custom-dropdown 组件设置为必需吗?

我的表单看起来像这样:

<form name="myform" (ngSubmit)="onSubmit()" #myform="ngForm">
    <!-- other fields omitted for brevity -->
    <my-custom-dropdown name="someValue" #someValue="ngModel" [(ngModel)]="model.someValue"></my-custom-dropdown>

    <button type="submit">Submit</button>
</form>

我的下拉组件基本上是一个自定义组件,看起来像这样:

<div>
    <label>
        Set some value
    </label>
    <p class="form-control-static">{{model.name}}</p>
    <ul>
        <my-custom-dropdown-item *ngFor="let option of options; let i = index" [(value)]="model" [option]="option"></my-custom-dropdown-item>
    </ul>
</div>

最后我有这样的下拉菜单:

<li>
    <!-- some structural and styling stuff omitted for brevity -->
    {{option.name}}
</li>

我正在使用最新版本的 Angular2。我没有包含 Typescript 文件,但长话短说,my-custom-dropdown 组件实现了 ControlValueAccessor。

【问题讨论】:

    标签: angular required form-fields


    【解决方案1】:

    我最终做的是一个简单的指令,我可以将它应用于下拉组件:

    import { Directive } from '@angular/core';
    import { AbstractControl, ValidatorFn, Validator, FormControl, NG_VALIDATORS } from '@angular/forms';
    
    //validation function
    function validateDropdownFactory(): ValidatorFn {
        return (c: AbstractControl) => {
            let isValid = c.value !== null;
    
            if (isValid) {
                return null;
            }
            else {
                return {
                    dropdownRequired: {
                        valid: false
                    }
                };
            }
        }
    }
    
    @Directive({
        selector: '[dropdownRequired][ngModel]',
        providers: [
            { provide: NG_VALIDATORS, useExisting: DropdownRequired, multi: true }
        ]
    })
    
    export class DropdownRequired implements Validator {
        validator: ValidatorFn;
    
        constructor() {
            this.validator = validateDropdownFactory();
        }
    
        validate(c: FormControl) {
            return this.validator(c);
        }
    }
    

    然后我这样应用它:

    <my-custom-dropdown name="someValue" #someValue="ngModel" [(ngModel)]="model.someValue" dropdownRequired></my-custom-dropdown>
    

    【讨论】:

      【解决方案2】:

      好吧,您的组件需要实现 ControlValueAccessor。对this topic 的一些很好的解释。 似乎 formControl 依赖于 NG_VALUE_ACCESSOR,如果不是请任何人提供一些不同的解决方案。 使组件成为必需的:

      1) 在选择器标签中,使用组件插入formControlName指令和ngModel的地方

      <drop-down [items]="itemsOfQuestionType" [label]="questionTypeLabel" (change)="onChooseQuestionType($event)" formControlName="questionTypeDropDown" [(ngModel)]="selectedQuestionTypeId"></drop-down>
      

      2) 代码中的某些地方需要定义验证规则。

      complexForm : FormGroup;
      formBuilder: FormBuilder;
      ngOnInit() {
          this.complexForm = this.formBuilder.group({
              questionTypeDropDown: ['', [Validators.required]]
          });
      }
      

      那么你就可以使用FormGroup的有效属性了。

      <button [disabled]="!complexForm.valid">Text</button>
      

      【讨论】:

        【解决方案3】:

        这取决于您是否已将实际下拉菜单定义为组件。

        如果您使用的是响应式表单,您应该能够轻松地将所需的验证器添加到您正在创建的控件中,如下所示:

         let myControl = new FormControl(null , Validators,required);
        

        这将使下拉菜单成为必需。

        如果您使用的是模板驱动的表单,您仍然可以拥有它,您只需将required=true 属性设置为元素。

        还有很多其他方法。

        就像,您可以创建一个指令,将所需字段添加到控件中,我猜 Angular2 已经这样做了。

        【讨论】:

        • 我正在使用模板驱动的表单。你认为我应该有这样的东西:
        • 不,它应该在实际的表单元素中,例如:
        • 你能举个例子吗?
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-13
        • 2017-11-26
        • 2023-04-08
        • 2017-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多