当“反应性表单”中的所有表单字段均需要时,我们如何设置Validators.required?

时间:2018-10-05 05:37:35

标签: angular typescript angular-reactive-forms angular-forms

角度v 4.4.3。

在反应式表单中,我们可以在每个表单字段如下编写Validators.required

this.loginForm = this.fb.group({
                firstName: ['', [Validators.required, Validators.maxLength(55)]],
                lastName: ['', Validators.required],
                age: [1, Validators.required],
                email: ['', Validators.required],
                username: ['', Validators.required],
                gender: ['', Validators.required],
                address: this.fb.group({
                    city: ['', Validators.required],
                    country: ['', Validators.required]
                })
            });

在这里,我们需要在每个表单字段上写Validators.required

因此,我正在寻找有角度的FormBuilder / FormControl的任何解决方案/方法,这些解决方案/方法可以设置所需的所有字段,并且可以根据需要在该字段上设置附加验证器。

3 个答案:

答案 0 :(得分:1)

您可以为整个表单创建一个customValidator,

this.form = this.fb.group({
  firstName: ['', [Validators.maxLength(55)]],
  ....
},
{
   validator: this.myValidator()
});


myValidator()
{
return (group: FormGroup) => {
    let errors:any={};
    let conError:boolean=false;
    if (!group.value.firstName)
    {
         errors.requiredFirstName=true;
         conError=true;
    }
     ....
    return conError? errors:null
  }
}

//。html变得像

<form [formGroup]="form " (ngSubmit)="onSubmit()">
    <div class="form-group">
         <label for="firstName">UserName</label>
         <input type="text" class="form-control"
             id="firstName" formControlName = "firstName">
     <!--see that we ask about form?.errors?requiredFirsName 
          requiredFirsName is the property we add to errors
         we add the condition is touched too 
         because else, at first, Angular show the error-->
             <span class="help-block" *ngIf="form?.errors?.requiredFirstName && 
     form.get('firstName').touched ">First Name required</span>
    </div>
    ....
   <!--just for check -->
   {{form?.errors |json}}
</form>

答案 1 :(得分:0)

您可以编写一个函数来对FormGroupFormArray进行深度迭代:

deepIterate(control: FormGroup | FormArray, iteratee: (control) => void): void {
    _.forEach(control.controls, control => {
        if (control instanceof FormControl) {
            iteratee(control);
        } else if (control instanceof FormGroup || control instanceof FormArray) {
            FormUtils.deepIterate(control, iteratee);
        }
    });
}

现在向每个required添加FormControl验证器,您可以使用此功能:

addRequiredValidators(control: FormGroup | FormArray): void {
    deepIterate(
        control,
        (control) => control.setValidators(Validators.compose([Validators.required, control.validator]))
    );
}

创建addRequiredValidators后,您可以致电FormGroup

答案 2 :(得分:0)

保持干净的态度。

selected.addListener((ObservableValue<? extends Boolean> obs, Boolean wasSelected, Boolean isSelected) -> {
    olTestModel.get(cbCell.getIndex()).setCheckbox(isSelected);
//=>TextFieldTableCell theTextFieldInThisRow = <HOW_DO_I_GET_THIS?>
    theTextFieldInThisRow.setEditable(isSelected);
});

创建带有必填字段/子字段的数组。在此数组的每个循环上执行操作,并创建表单控件。

例如:How to add dynamically FormControl to FormGroup

或者,如果您只关心package test24; import javafx.application.Application; import static javafx.application.Application.launch; import javafx.beans.Observable; import javafx.beans.property.BooleanProperty; import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.StringProperty; import javafx.beans.value.ObservableValue; import javafx.collections.FXCollections; import javafx.collections.ListChangeListener; import javafx.collections.ObservableList; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.control.TableColumn; import javafx.scene.control.TableView; import javafx.scene.control.cell.CheckBoxTableCell; import javafx.scene.control.cell.TextFieldTableCell; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import javafx.util.Callback; public class Test24 extends Application { private Parent createContent() { //******************************************************************************************** //Declare the TableView and its underlying ObservableList and change listener TableView<TestModel> table = new TableView<>(); ObservableList<TestModel> olTestModel = FXCollections.observableArrayList(testmodel -> new Observable[] { testmodel.checkboxProperty() }); olTestModel.addListener((ListChangeListener.Change<? extends TestModel > c) -> { while (c.next()) { if (c.wasUpdated()) { boolean checkBoxIsSelected = olTestModel.get(c.getFrom()).getCheckbox().booleanValue(); //PLAN A: Set editability here //==>TextFieldTableCell theTextFieldInThisRow = <HOW_DO_I_GET_THIS?> //theTextFieldInThisRow.setEditable(checkBoxIsSelected); } } }); olTestModel.add(new TestModel(false, "A")); olTestModel.add(new TestModel(false, "B")); olTestModel.add(new TestModel(false, "C")); table.setItems(olTestModel); //******************************************************************************************** //Declare the text column whose editability needs to change depending on whether or //not the CheckBox is ticked TableColumn<TestModel, String> colText = new TableColumn<>("text"); colText.setCellValueFactory(cellData -> cellData.getValue().textProperty()); colText.setCellFactory(TextFieldTableCell.<TestModel>forTableColumn()); colText.setEditable(false); //******************************************************************************************** //Declare the CheckBox column TableColumn<TestModel, Boolean> colCheckbox = new TableColumn<>("checkbox"); colCheckbox.setCellValueFactory(cellData -> cellData.getValue().checkboxProperty()); colCheckbox.setCellFactory((TableColumn<TestModel, Boolean> cb) -> { final CheckBoxTableCell cbCell = new CheckBoxTableCell<>(); final BooleanProperty selected = new SimpleBooleanProperty(); cbCell.setSelectedStateCallback(new Callback<Integer, ObservableValue<Boolean>>() { @Override public ObservableValue<Boolean> call(Integer index) { return selected; } }); selected.addListener((ObservableValue<? extends Boolean> obs, Boolean wasSelected, Boolean isSelected) -> { //Set the value in the data model olTestModel.get(cbCell.getIndex()).setCheckbox(isSelected); //PLAN B: Set editability here //Set the editability for the text field in this row //==> TextFieldTableCell theTextFieldInThisRow = <HOW_DO_I_GET_THIS?> //theTextFieldInThisRow.setEditable(isSelected); }); return cbCell; }); //******************************************************************************************** //Column to show what's actually in the TableView's data model for the checkbox TableColumn<TestModel, Boolean> colDMVal = new TableColumn<>("data model value"); colDMVal.setCellValueFactory(cb -> cb.getValue().checkboxProperty()); colDMVal.setEditable(false); table.getSelectionModel().setCellSelectionEnabled(true); table.setEditable(true); table.getColumns().add(colCheckbox); table.getColumns().add(colDMVal); table.getColumns().add(colText); BorderPane content = new BorderPane(table); return content; } public class TestModel { private BooleanProperty checkbox; private StringProperty text; public TestModel() { this(false, ""); } public TestModel( boolean checkbox, String text ) { this.checkbox = new SimpleBooleanProperty(checkbox); this.text = new SimpleStringProperty(text); } public Boolean getCheckbox() { return checkbox.get(); } public void setCheckbox(boolean checkbox) { this.checkbox.set(checkbox); } public BooleanProperty checkboxProperty() { return checkbox; } public String getText() { return text.get(); } public void setText(String text) { this.text.set(text); } public StringProperty textProperty() { return text; } } @Override public void start(Stage stage) throws Exception { stage.setScene(new Scene(createContent())); stage.setTitle("Test"); stage.setWidth(500); stage.show(); } public static void main(String[] args) { launch(args); } } ,那么@Ludevik的答案是最好的选择,但是对于angular来说,这将是额外的工作-首先,您要定义表单控件,然后再定义[{ "firstname": "" "required": "true/false", "pattern" :"" }, { "lastname": "" "required": "true/false", "pattern" :"" }] < / p>