角度:在更改另一个表单控件时触发表单控件验证

时间:2019-04-18 08:17:31

标签: angular angular-reactive-forms angular-custom-validators

请以堆叠方式引用该项目 here

可以看出,我的反应形式为firstNumbersecondNumberthirdNumber。我需要对表单控件thirdNumber进行验证,以使其值不应大于firstNumbersecondNumber中具有最小值的表单控件的值。

每当表单控件validateThirdNumber更改时,组件中的自定义验证器thirdNumber都可以正常工作,但是我需要 也可以根据表单控件firstNumbersecondNumber的更改触发其验证,因为验证逻辑可以根据表单控件的更改而更改 firstNumbersecondNumber

为此,我在表单控件firstNumbersecondNumber的更改中添加了一个事件,其中我将表单控件thirdNumber标记为touched,但其验证确实似乎没有被触发。

那么,如何在表单控件thirdNumberfirstNumber更改时触发表单控件secondNumber的验证?

此外,即使在将this.myFormGroup绑定到其表单控件声明和{之后,为什么在自定义验证器中有时未定义app.componen.ts(请参阅{{1}上line:22中的日志) {1}中定义了{1}}?

2 个答案:

答案 0 :(得分:0)

您最好的选择是创建自己的自定义全局验证器。

class ValidateThirdNumber {
    static validate(control: AbstractControl) {
          console.log(control);
        if(control) {
           const firstNumber = control.get('firstNumber').value;
           const secondNumber = control.get('secondNumber').value;
           const thirdnumber = control.get('thirdNumber').value;
        if (firstNumber > secondNumber) {
          if (thirdnumber > secondNumber) {
            control.get('thirdNumber').setErrors( {greaterThanSecondNumber: true} );   
          }
        } else if (firstNumber < secondNumber) {
          if (thirdnumber > firstNumber) {
              control.get('thirdNumber').setErrors( {greaterThanFirstNumber: true} ); 
          }
        }
        }
        return null;
        }
}

表单组的初始化应为:

 this.myFormGroup = this.fb.group({
      firstNumber: [0],
      secondNumber: [0],
      thirdNumber: [0]
    }, {validator: [ValidateThirdNumber.validate] });

您不再需要感动的属性

<span *ngIf="myFormGroup.get('thirdNumber').errors?.greaterThanFirstNumber">
  Third number cannot be greater than First Number
 </span>
    <span *ngIf=" myFormGroup.get('thirdNumber').errors?.greaterThanSecondNumber">
  Third number cannot be greater than Second Number
 </span>

您也不需要(change)事件将其删除

答案 1 :(得分:0)

如果您想使用它,我已经创建了一个更简单的选项。不使用表单控件验证。

class AddItemViewController : FormViewController {

    var delegate : CanReceive?

    var title, description, category : String?

    static let dateFormatter: DateFormatter = {
        let formatter = DateFormatter()
        formatter.dateFormat = "MMM d yyyy, h:mm a"
        return formatter
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        form +++ Section()
            <<< TextRow(){
                $0.title = "Title"
                $0.placeholder = "Enter text here"
                $0.onChange { [unowned self] row in
                    self.title = row.value
                }
            }
            <<< TextRow(){
                $0.title = "Description"
                $0.placeholder = "Give some description"
                $0.onChange { [unowned self] row in
                    self.description = row.value
                }
            }

            <<< AlertRow<String>() {
                $0.title = "Category"
                $0.selectorTitle = "Select the category"

                $0.options = ["Personal ", "Home ", "Work ", "Play ", "Health ‍♀️" , "Other"]
                $0.onChange { [unowned self] row in
                    self.category = row.value
                }
                }

            +++ Section(){ section in
                section.header = {
                    var header = HeaderFooterView<UIView>(.callback({
                        let button = UIButton(frame: CGRect(x: 100, y: 100, width: 50, height: 50))
                        button.backgroundColor = .darkGray
                        button.setTitle("Save Item", for: .normal)
                        button.addTarget(self, action: #selector(self.buttonAction), for: .touchUpInside)

                        return button
                    }))
                    header.height = { 50 }
                    return header
                }()
        }
    }

    @objc func buttonAction(sender: UIButton) { // no implicit unwrapped optional
        let todoItem = ToDo(title: title, description: description, category : category)
        delegate?.dataReceived(data: todoItem)
        self.dismiss(animated: true, completion: nil)

        print("Button tapped")
    }
}

并删除<div> <form [formGroup]="myFormGroup" #formRef="ngForm"> First number:<input #firstNum type="number" formControlName="firstNumber"><br/> Second number:<input #secondNum type="number" formControlName="secondNumber"><br/> Third number:<input #thirdNum type="number" formControlName="thirdNumber"><br/> <span *ngIf="firstNum && thirdNum && (thirdNum.value > firstNum.value)"> Third number cannot be greater than First Number </span> <hr> <span *ngIf="secondNum && thirdNum && (thirdNum.value > secondNum.value)"> Third number cannot be greater than Second Number </span> </form> </div> 文件中的所有验证。

如果您开始创建较大的组件,则最好使用表单验证选项。