加载数据后设置反应形式(异步) - Angular 5 [英] Set reactive form after data loaded (async) - Angular 5

查看:23
本文介绍了加载数据后设置反应形式(异步) - Angular 5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在从 API 加载值后更新表单值.我尝试使用 *ngIf 技术,但即使设置了表单,该表单也不可见.

我无法分享完整的项目,但这是组件模板和控制器

模板

<h3>编辑新闻 </h3>

<div class="partner-add-form"><ng-container *ngIf='newsForm'><form action="" [formGroup]='newsForm' (ngSubmit)="onSubmit()"><div class="row"><div class="input-field col s12 tooltip"><input formControlName='title' [id]="'title'" [type]="'text'"><label [for]="'title'">Title</label><validator-errors [control]='newsForm.get("title")'></validator-errors>

<div class="input-field col s12 tooltip"><textarea class="materialize-textarea" formControlName='content' [id]="'content'"></textarea><label [for]="'content'">Content</label><validator-errors [control]='newsForm.get("content")'></validator-errors>

<div class="input-field col s12 margin-reset"><mat-form-field class="full-width"><mat-select [formControl]='newsForm.controls["partner_id"]'><mat-option disabled selected>Categories</mat-option><mat-option *ngFor="let partner of partners.data" [value]="partner.id">{{partner.name }} </mat-option></mat-select></mat-form-field><validator-errors [control]='newsForm.controls["partner_id"]'></validator-errors>

<div class="file-field col s12 input-field"><div class="btn"><span>文件</span><input(change)="fileChangeListener($event)" type="file">

<div class="file-path-wrapper"><input class="file-path validate" type="text" placeholder="上传一个或多个文件">

<div class="col s12"><div class="flex flex-middle flex-center crop-area"><img-cropper #cropper [image]="data" [settings]="cropperSettings"></img-cropper><i class="material-icons">arrow_forward</i><div class="结果四舍五入 z-depth-1"><img [src]="data.image " *ngIf="data.image " [width]="cropperSettings.croppedWidth"[height]="cropperSettings.croppedHeight">

<div class="col s12 form-b​​ottom"><div class="left"><button type="button" onclick='window.history.back()' class='btn btn-large wave-effect wave-light '><i class="material-icons">keyboard_arrow_left</i><span>返回</span>

<div class="right"><button [ngClass]="{'disabled':(newsForm['invalid']) || isSubmitting || !data.image }" type="submit" class='btn btn-large wave-effect wave-light'>提交</button>

</表单></ng-容器>

控制器

 合作伙伴;新闻 = {};新闻表格:表格组;ngOnInit() {setTimeout(() => {this._dashboardService.routeChangeStarted();}, 0);this._activatedRoute.params.subscribe(params => {this.news["id"] = params["id"];this.getPartners().then(data => {this.getNews().then(data=>{this.setForm();})});});}设置表格(){this.newsForm = this._formBuilder.group({标题: [this.news['title'], [Validators.required]],内容:[this.news['content'], [Validators.required]],partner_id: [this.news['partner']['id'], [Validators.required]]});console.log(new Boolean(this.newsForm));}获取合作伙伴(){返回承诺((res,rej)=> {setTimeout(() => {this._dashboardService.progressStarted();this._dashboardService.routeChangeStarted();}, 0);this._partnerService.getPartners().subscribe(合作伙伴 =>{如果(partners.status == 200){this.partners = 合作伙伴;res(partners.data);} 别的 {this._errorActions.errorHandler(partners.status);}setTimeout(() => {this._dashboardService.progressFinished();this._dashboardService.routeChangeFinished();}, 0);},错误 =>{this._notificationService.warning("UPS,出了点问题");});});}获取新闻(){setTimeout(() => {this._dashboardService.routeChangeStarted();this._dashboardService.progressStarted();}, 0);返回承诺((res,rej)=> {this._newsService.getNews(this.news["id"]).subscribe(数据 =>{如果(数据[状态"] == 200){Object.assign(this.news, data["data"]);res(this.news);} 别的 {this._errorActions.errorHandler(data["status"]);}setTimeout(() => {this._dashboardService.progressFinished();this._dashboardService.routeChangeFinished();}, 0);},错误 =>{this._notificationService.error("UPS,出了点问题");});});}

有什么问题?设置表单后,它甚至不显示表单本身.从 API 加载数据后,还有其他设置表单值的方法吗?

解决方案

您可以创建一个单独的函数来用数据填充表单.您可以在从 API 获取数据后调用此函数.

变体 1:setValue

官方角度文档:setValue

<块引用>

使用 setValue,您可以通过传入属性与 FormGroup 背后的表单模型完全匹配的数据对象来一次性分配每个表单控件值.

示例:

updateValues(dataObject: any) {this.heroForm.setValue({名称:this.hero.name,地址:this.hero.addresses[0] ||新地址()});}

变体 2:patchValue

官方角度文档:patchValue

<块引用>

使用 patchValue,您可以通过为感兴趣的控件提供键/值对对象,为 FormGroup 中的特定控件分配值.

示例:

updateValues(dataObject: any) {this.heroForm.patchValue({名称:this.hero.name});}

I am trying to update the form values after loading values from an API. I tried using the *ngIf technique but the form is not visible even when the form is set.

I am not able to share the full project, but here is the component template and controller

Template

<div class="page-title">
  <h3> Edit news </h3>
</div>
<div class="partner-add-form">
  <ng-container *ngIf='newsForm'>
    <form action="" [formGroup]='newsForm' (ngSubmit)="onSubmit()">
      <div class="row  ">
        <div class="input-field col s12 tooltip">
          <input formControlName='title' [id]="'title'" [type]="'text'">
          <label [for]="'title'">Title</label>
          <validator-errors [control]='newsForm.get("title")'></validator-errors>
        </div>
        <div class="input-field col s12 tooltip">
          <textarea class="materialize-textarea" formControlName='content' [id]="'content'"></textarea>
          <label [for]="'content'">Content</label>
          <validator-errors [control]='newsForm.get("content")'></validator-errors>
        </div>
        <div class="input-field col s12 margin-reset">
          <mat-form-field class="full-width">
            <mat-select [formControl]='newsForm.controls["partner_id"]'>
              <mat-option disabled selected>Categories</mat-option>
              <mat-option *ngFor="let partner of partners.data" [value]="partner.id">
              {{ partner.name }} </mat-option>
            </mat-select>
          </mat-form-field>
          <validator-errors [control]='newsForm.controls["partner_id"]'></validator-errors>
        </div>
        <div class="file-field col s12 input-field">
          <div class="btn">
            <span>File</span>
            <input (change)="fileChangeListener($event)" type="file"> </div>
          <div class="file-path-wrapper">
            <input class="file-path validate" type="text" placeholder="Upload one or more files"> </div>
        </div>
        <div class="col s12">
          <div class="flex flex-middle flex-center crop-area">
            <img-cropper #cropper [image]="data" [settings]="cropperSettings"></img-cropper>
            <i class="material-icons">arrow_forward</i>
            <div class="result rounded z-depth-1">
              <img [src]="data.image " *ngIf="data.image " [width]="cropperSettings.croppedWidth"
                [height]="cropperSettings.croppedHeight"> </div>
          </div>
        </div>
        <div class="col s12 form-bottom">
          <div class="left">
            <button type="button" onclick='window.history.back()' class='btn btn-large waves-effect waves-light '>
              <i class="material-icons">keyboard_arrow_left</i>
              <span>Back</span>
            </button>
          </div>
          <div class="right">
            <button [ngClass]="{'disabled':(newsForm['invalid']) || isSubmitting || !data.image }" type="submit" class='btn btn-large waves-effect waves-light '>
            Submit </button>
          </div>
        </div>
      </div>
    </form>
  </ng-container>
</div>

Controller

  partners;

  news = {};
  newsForm: FormGroup;

  ngOnInit() {
    setTimeout(() => {
      this._dashboardService.routeChangeStarted();
    }, 0);
    this._activatedRoute.params.subscribe(params => {
      this.news["id"] = params["id"];
      this.getPartners().then(data => {
        this.getNews().then(data=>{
          this.setForm();
        })
      });
    });
  }

  setForm() {
    this.newsForm = this._formBuilder.group({
     title: [this.news['title'], [Validators.required]],
     content: [this.news['content'], [Validators.required]],
     partner_id: [this.news['partner']['id'], [Validators.required]]
    });
    console.log(new Boolean(this.newsForm));
  }

  getPartners() {
    return Promise((res, rej) => {
      setTimeout(() => {
        this._dashboardService.progressStarted();
        this._dashboardService.routeChangeStarted();
      }, 0);
      this._partnerService.getPartners().subscribe(
        partners => {
          if (partners.status == 200) {
            this.partners = partners;
            res(partners.data);
          } else {
            this._errorActions.errorHandler(partners.status);
          }
          setTimeout(() => {
            this._dashboardService.progressFinished();
            this._dashboardService.routeChangeFinished();
          }, 0);
        },
        error => {
          this._notificationService.warning("Ups, something went wrong");
        }
      );
    });
  }

  getNews() {
    setTimeout(() => {
      this._dashboardService.routeChangeStarted();
      this._dashboardService.progressStarted();
    }, 0);

    return Promise((res, rej) => {
      this._newsService.getNews(this.news["id"]).subscribe(
        data => {
          if (data["status"] == 200) {
            Object.assign(this.news, data["data"]);
            res(this.news);
          } else {
            this._errorActions.errorHandler(data["status"]);
          }
          setTimeout(() => {
            this._dashboardService.progressFinished();
            this._dashboardService.routeChangeFinished();
          }, 0);
        },
        error => {
          this._notificationService.error("Ups, something went wrong");
        }
      );
    });
  }

What is the problem? It doesn't even show the form itself after setting the form. Is there another way of setting the form values after loading the data from an API?

解决方案

You can create a separate function to fill your form with data. You can call this function after getting data from an API.

Variant 1: setValue

Official angular documentation: setValue

With setValue, you assign every form control value at once by passing in a data object whose properties exactly match the form model behind the FormGroup.

Example:

updateValues(dataObject: any) {
  this.heroForm.setValue({
    name:    this.hero.name,
    address: this.hero.addresses[0] || new Address()
  });
}

Variant 2: patchValue

Official angular documentation: patchValue

With patchValue, you can assign values to specific controls in a FormGroup by supplying an object of key/value pairs for just the controls of interest.

Example:

updateValues(dataObject: any) {
  this.heroForm.patchValue({
    name: this.hero.name
  });
}

这篇关于加载数据后设置反应形式(异步) - Angular 5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆