Angular 4 - 重置表单使插入的模型在视图中填充空值

Posted

技术标签:

【中文标题】Angular 4 - 重置表单使插入的模型在视图中填充空值【英文标题】:Angular 4 – reset form makes inserted model filled with null values in a view 【发布时间】:2018-07-31 08:23:55 【问题描述】:

我想在提交后重置表单。分别地,我的用例如下:

 1. Fill form (template-driven solution).
 2. Get model from form and with service pass it to the database.

     2.1. Add model to database
     2.2. Assign model to an array

 3. Update view by this updated array.

问题是,如果我在调用我的服务方法后重置表单,发送到数据库的数据是有效的,但在客户端我收到空值——这意味着在刷新 Angular 客户端(浏览器)时,数据已完全加载没有任何错误。另一方面,如果不包含重置方法,则一切正常,正如预期的那样——只有表单没有重置(逻辑上)。

我尝试调试我的解决方案,或多或少没有成功。然而,我想到了一个想法。在那个服务层进行了异步调用,是否有可能重置表单的方法可以在处理请求的过程中偏向参数,方法addCrop

组件

Injectable()
export class CropsComponent implements OnInit 
            
options$ : Observable<StyleModel[]>;
crop$;
documentTypes = ['Pdf','LaTeX'];
//used for binding in form
cropModel : CropModel;

constructor(private _styleService: StyleRepositoryService)  
            
ngOnInit() 
  this._styleService.getCropOnChange().subscribe(crop => this.cropModel = crop);
  this.options$ = this._styleService.getStylesOnChange();

            
onSubmit(f:NgForm)

  if(f.valid)
  //calling service layer for storing this model in database
  this._styleService.addCrop(this.cropModel);
  //resetting form values
  f.reset();
  
 

服务

@Injectable()
export class StyleRepositoryService 

  /*
     [abbrev.]
  */

    addCrop(crop: CropModel)
        this.dataService.createCrop(crop).subscribe(data =>
            //find style according to CropModel styleId. Style model include array of cropModels
            let stl = this.styles.find(p => p.styleId == data.styleId);
            //add this cropModel to found style
            stl.styleCrops.push(crop);

           //log inform me about added model with null values
            console.log(this.styles);

            //notify other components that styles array have updated.
            this.styles$.next(this.styles);
        )
    

  /*
     [abbrev.]
  */


服务请求成功 - 模型已添加到数据库。正如我在顶部提到的。传递的参数crop是否有可能被reset form方法拦截,即使它已经传递了?因此,当我将模型(来自addCrop 方法的参数)添加到数组模型时,模型为空。

编辑

addCrop 方法运行返回数据的 post 请求 - 后端服务器返回与在 Angular 中创建的模型相同的模型。因此,如果我使用返回的数据,则视图会正确更改。 所以澄清一下问题。 reset form方法能否改变属性的值 crop addCrop 方法运行到一半?

  addCrop(crop: CropModel)
        this.dataService.createCrop(crop).subscribe(data =>
            //find style according to CropModel styleId. Style model include array of cropModels
            let stl = this.styles.find(p => p.styleId == data.styleId);
            //add this cropModel to found style
            //instead using parameter crop, I used returned model from backend, data
            stl.styleCrops.push(data);

           //log inform me about added model with null values
            console.log(this.styles);

            //notify other components that styles array have updated.
            this.styles$.next(this.styles);
        )
    

【问题讨论】:

如果您没有将任何内容传递给重置,它会将表单重置为初始(空/空)状态。尝试将您的值传递给 reset 以使用当前值重置表单。 @DeborahK 在重置方法中我尝试通过新创建的模型。表格显然已重置。但是,问题仍然存在 - 仍然认为我得到的是空值。实际的问题是,可以在 addCrop 方法中形成重置方法偏差参数吗?这样,对数据库的操作就被执行了,但是一旦订阅了方法中的参数就会改变? 再仔细看看你的代码,流程是问题的一部分。我假设this.dataService.createCrop 是异步操作?所以f.reset() 在该操作完成之前发生。由于您在操作完成时发送通知 (this.styles$.next),因此您可以将重置逻辑移至订阅中。 【参考方案1】:

根据@DeborahK,我发现了两个问题。

    了解如何进行异步调用很重要。对于我作为 Angular 的新手来说,这是一个很好的观点(感谢@DeborahK),这让我更好地思考代码中的流程。

    但主要问题在于传递参数。在onSubmit 方法中,我将引用类型cropModel 传递给服务方法addCrop。问题是,该表单引用了相同的对象 - cropModel,因为它已绑定。所以如果我重置表单,我会为引用的对象设置值(空值)——在这种情况下是cropModel。并且因为方法addCrop 进行异步调用,所以可以在调用期间将cropModel 设置为null。

解决方案很简单。在属性cropModel 的值内初始化新对象并将其传递给方法addCrop

解决方案

 onSubmit(f:NgForm)
  
    if(f.valid)
      this._styleService.addCrop(new CropModel(this.cropModel.bottomMargin,
        this.cropModel.leftMargin,
         this.cropModel.rightMargin,
          this.cropModel.topMargin, 
          this.cropModel.styleId,
          this.cropModel.documentType));
      f.reset();
    
  

【讨论】:

以上是关于Angular 4 - 重置表单使插入的模型在视图中填充空值的主要内容,如果未能解决你的问题,请参考以下文章

Angular 4 表单重置提交到服务器

Angular 2组件模型刷新视图,无需模型更改

我们如何使 htmx 响应触发表单重置?

如何在 ANGULAR 2 中提交表单时重置表单验证

如何使用 Angular 重置自定义表单控件

formGroupDirective 用于重置表单 - Angular 反应式表单