根据组件输入属性

时间:2018-01-27 21:39:08

标签: angular

我有一个带有反应形式的Angular 5组件,我想基于通过@Input传入的属性值来验证其中一个字段,这些属性可能会发生变化。当我尝试各种解决方案时,我没有运气并且导致错误。这是我到目前为止(不相关的代码被删除)。

感谢您的帮助,非常感谢您对示例的指示。

@Component({
  selector: 'app-fief-budget',
  templateUrl: './fief-budget.component.html',
  styleUrls: ['./fief-budget.component.scss']
})
export class FiefBudgetComponent implements OnInit {
  @Input('manor') manor: Manor;

....

  createForm() {
    this.budgetForm = this.fb.group({
      woodsWorked: [0, [Validators.required, Validators.min(0), this.validateMaxWoodacres]]
    });
  }

....

  validateMaxWoodacres(): ValidatorFn {
    return (c: FormControl) => {
      if (this.manor) {
        return c.value > this.manor.woodlandAcres ? { 'validateMaxWoodacres': {valid: false} } : null;
      }
      return null;
    };
  }
}

3 个答案:

答案 0 :(得分:0)

您正在尝试的不会工作,您需要在输入更改时更新验证器:

private _manor: Manor;

@Input('manor')
set manor(manor: Manor) {
  this._manor = manor;
  // you can either update the form validators or just the validator of a single control
  this.bugetForm.setValidators(...)
}

get manor(): Manor {
  return this._manor;
}

答案 1 :(得分:0)

当我们使用函数创建验证器时,我们需要调用函数 - 来放置() -

Compilation Error... 
prog.cpp: In function 'void connect(Node*)':
prog.cpp:120:23: error: void value not ignored as it ought to be
        Node* nn=q.pop();
                       ^

小心,如果您希望在创建表单后更改“庄园”的值,则必须再次检查表单以再次验证。那你必须做一些像

 this.budgetForm = this.fb.group({
      woodsWorked: [0, [Validators.required, Validators.min(0),
                        this.validateMaxWoodacres()]] //<--see the "parenthesis
    });

注意:如果我们写没有括号

  _manor:any;
  @Input('manor') 
  set manor(value){ //If a change of manor happens
    this._manor=value;
    if (this.budgetForm)  //if this.budgetForm
          this.budgetForm.get('woodsWorked').updateValueAndValidity(); //validate the control again
  }
  get manor() {
    return this._manor;
  }

我们的功能必须简单

this.budgetForm = this.fb.group({
      woodsWorked: [0, [this.validateMaxWoodacres]] //without parenthesis
    });

答案 2 :(得分:0)

谢谢大家的回复。我确实想到了这一点,并希望在这里发布其他寻求解决方案的人。输入setter / getter方法存在问题,因为它会在定义表单之前触发,并且不会像我期望的那样更新。 (重新)设置验证器的建议虽然让我走在正确的道路上,所以谢谢你。

最终这对我来说实际上起作用的对我们来说是DoCheck生命周期钩子来重置验证器,而且我还必须调用更新值和有效性。所以我最初在表单上设置验证器并在组件类中重置它们,因为max更新为manor.woodlandAcres的当前值,所以不需要自定义验证。

  ngDoCheck() {
    this.budgetForm.controls['woodsWorked'].setValidators([
      Validators.required,
      Validators.min(0),
      Validators.max(this.manor.woodlandAcres)]);
    this.budgetForm.controls['woodsWorked'].updateValueAndValidity();
  }