【问题标题】:Angular 2, unable to patch value to form controlsAngular 2,无法修补值以形成控件
【发布时间】:2017-06-21 19:40:19
【问题描述】:

在我的 Angular 2 应用程序中,我有一个编辑分配组件,当用户单击编辑按钮时会加载该组件。它显示一个表单并使用来自 firebase 数据库的现有值填充所有表单控件,然后用户可以对其进行编辑。当我第一次单击编辑按钮时,它会加载表单控件中的所有值。然后,如果我返回或导航到任何其他链接,然后再次单击编辑按钮,表单控件不会修补 firebase 数据库中的值。

下面的图片将帮助您更好地理解问题:

我第一次点击编辑按钮一切正常

然后,如果我返回某个其他链接,然后再次单击编辑按钮返回,则表单不会使用 firebase 数据库中的值修补表单控件。

我正在像这样验证我的表单

constructor(
  private _routeParams: ActivatedRoute,
  private _db: AngularFireDatabase,
  private _fb: FormBuilder,
  private _uploadService: UploadService,
  private _getAsnService: GetAssignmentService,
  private _editAsnSvc: EditAssignmentService,
) { 
  console.log("in constructor");
  this.validate();
}

ngOnInit() {
  console.log("in init");
  this.getRouteParams();
  this.assignment = this._getAsnService.getAssignment(this.asnDetailKey); // this.assignment is FirebaseObjectObservable retrieved from firebase DB
  this.setInputValues();
  this.getCourses();
  this.validate();
}

validate() {
this.form = this._fb.group({
  course: ['', Validators.compose([Validators.required])],
  batch: ['', Validators.compose([Validators.required])],
  subject: ['', Validators.compose([Validators.required])],
  name: ['', Validators.compose([Validators.required])],
  description: ['', Validators.compose([Validators.required])],
  dueDate: ['', Validators.compose([Validators.required])]
  });
  this.today = new Date().toJSON().split('T')[0];
}

setInputValues() {
  this.assignment.subscribe(asnDetails => {
  console.log("setting values"); // <----- These are the values you see in console
  this._assignment = asnDetails;
  console.log(this._assignment); // <----- _assignment contains all values but form controls are unable to patch them
  this.form.get('course').patchValue(this._assignment.course);
  this.form.get('batch').patchValue(this._assignment.batch);
  this.form.get('subject').patchValue(this._assignment.subject);
  this.form.get('name').patchValue(this._assignment.AsnName);
  this.form.get('description').patchValue(this._assignment.AsnDesc);
  this.form.get('dueDate').patchValue(this._assignment.dueDate);

  this.batches = this._db.list('/batches/' + this._assignment.course);
});
}

谢谢

* 已编辑 *

我删除了 setInputValues 方法并在 validateForm 方法中进行了验证(我将名称从 validate 更改为 validateForm),方法是按照 @developer033 的指示将 asnDetails 传递给它

 ngOnInit() {
this.getRouteParams();
this.assignment = this._getAsnService.getAssignment(this.asnDetailKey);
this.assignment.subscribe(asnDetails => this.validateForm(asnDetails));
this.getCourses();
}

 validateForm(asnDetails) {
this.form = this._fb.group({
  course: [asnDetails.course, Validators.compose([Validators.required])],
  batch: [asnDetails.batch, Validators.compose([Validators.required])],
  subject: [asnDetails.subject, Validators.compose([Validators.required])],
  name: [asnDetails.AsnName, Validators.compose([Validators.required])],
  description: [asnDetails.AsnDesc, Validators.compose([Validators.required])],
  dueDate: [asnDetails.dueDate, Validators.compose([Validators.required])]
});
this.today = new Date().toJSON().split('T')[0];
this.batches = this._db.list('/batches/' + asnDetails.course);
}

我还创建了一个 initForm 方法,并从构造函数中调用它来初始化表单。

  initForm() {
this.form = this._fb.group({
  course: ['', Validators.compose([Validators.required])],
  batch: ['', Validators.compose([Validators.required])],
  subject: ['', Validators.compose([Validators.required])],
  name: ['', Validators.compose([Validators.required])],
  description: ['', Validators.compose([Validators.required])],
  dueDate: ['', Validators.compose([Validators.required])]
});
}

我认为这是动态验证模型驱动表单的更简洁的方法。

【问题讨论】:

  • 你为什么不简化它并设置validate()中的所有值?其实你不需要setInputValues()
  • 动态怎么做?我需要将赋值对象作为参数传递给验证吗?抱歉,我是 Angular 新手。
  • 是的,将assignment 传递给您的validate()(也可以考虑重命名此函数)。此外,不需要Validators.compose。见this plunker
  • 帮助很大。非常感谢:)

标签: forms angular validation firebase


【解决方案1】:

您的validate() 方法实际上是错误的。它使用默认值和自动执行的验证器初始化表单。 validate() 这个名字具有误导性。在您的情况下,您每次都使用this._fb.group() 创建一个新表单,并且您丢失了所有以前的值。第一次它只是工作,因为请求需要一些时间,同时您的 validate() aka initializeForm() 方法确实运行了。我猜在所有其他情况下,请求可能会被缓存,因此在您的 validate 方法之前调用 setInputValues。只需在拨打asnService 之前将电话转至validate(),您应该会很好。问候克里斯

【讨论】:

  • 谢谢克里斯。它有帮助:)
猜你喜欢
  • 2019-04-12
  • 1970-01-01
  • 2021-03-12
  • 1970-01-01
  • 2017-04-02
  • 2022-01-21
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多