Angular 5 - 如何让日期管道在第一个表单构建后以动态表单正确呈现?

Angular 5 - How to get the date pipe to correctly render in a dynamic form after the first form build?

Angular 5.2.4 - 尽管 reset()

但日期管道失败的反应形式

我正在创建一个动态生成的响应式表单。我的示例中只有一个控件,它显示日期。日期应该由日期管道(在模板中)格式化,并且在第一次构建表单时正确地这样做。但是,在连续的表单构建中,日期呈现为日期字符串,没有管道应用的格式。

在每个表单构建中,我调用 FormGroup.reset(),并且还尝试将 FormGroup 设置为 null。

编辑:回答这个问题后,我将管道转换移到了 .ts 文件中。这将适用于许多情况,尽管在某些情况下它不适用于更复杂的生成表单。所以对于很多人来说,这个解决方案会奏效。

我在下面包含了我的代码,并清楚地标记了我在收到答案后所做的更改。在这个 post.

的底部也发现了一个 Stackblitz link 和同样的代码

这是我开始使用的 .ts 代码(我在评论中注意到了我的更改):

import { Component } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
// ***added this DatePipe import after the answer***
import { DatePipe } from '@angular/common'; 

@Component({
  selector: 'material-app',
  templateUrl: 'app.component.html',
  styleUrls: ['./app.component.css'],
   // ***added following line after the answer***
  providers: [DatePipe]
})
export class AppComponent {
  formGroup: FormGroup;
  importantDate = "2018-08-22T12:34:56.789Z";
  anotherDate = "2015-11-00T01:23:45.678Z";
  test = 0;

 // *** added DatePipe injection to constructor after answer***
  constructor(private datePipe: DatePipe) { }

  ngOnInit() {
    this.buildForm(this.importantDate);
  }

 // ***added this function after the answer***
  transformDate(date) {
    return this.datePipe.transform(date, 'MM/dd/yyyy');
  }

  // build the form the first time
  buildForm(dateValue) {
    this.formGroup = new FormGroup({
      dateEnjoined: new FormControl(this.importantDate)
 /**NOTE: alternatively, "dateEnjoined: new FormControl(this.transformDate(dateValue))" would 
also work here. But the template pipe handles the first transformation OK.*/
    });
  }

// this is my original function to rebuild the form
  unSetAndRebuildForm_OLD_VERSION() {
    if (this.formGroup.get('dateEnjoined').value == this.anotherDate) {
      this.formGroup.reset({ dateEnjoined: this.importantDate });
      this.test = 0;
    } else {
      this.formGroup.reset({ dateEnjoined: this.anotherDate });
      this.test = 1;
    }
  }

// *** I altered the function to this version, after the answer***
  unSetAndRebuildForm() {
    if (this.test == 1) {
      this.formGroup.reset();
      this.formGroup.patchValue({ dateEnjoined: this.transformDate(this.importantDate) });
      this.test = 0;
    } else {
      this.formGroup.reset();
      this.formGroup.patchValue({ dateEnjoined: this.transformDate(this.anotherDate) });
      this.test = 1;
    }
  }
}

这是表单的 .html 代码(无需更改)。我已将日期管道留在表单中(到目前为止,这不会中断,并且允许表单反映从服务器接收到的更新值,而无需强制重建表单)。另外,请注意我确实在 "value":

周围留下了方括号 []
<form class="basic-container" [formGroup]="formGroup">
  <input formControlName="dateEnjoined" 
  [value]="importantDate |  date: 'MM/dd/yyyy'">
  <button (click)="unSetAndRebuildForm()">  click me </button>
</form>

回答完后,在我的AppModule.ts中,我还需要导入DatePipe并添加到providers数组中(在实际应用中,我在SharedModule):

import { DatePipe } from '@angular/common';

providers: [ DatePipe ]

https://stackblitz.com/edit/ang5-date-pipe-fails-after-first-build

我们也可以从组件端调用datepipe。另外,我们需要导入 DatePipe 作为组件提供者

    import { DatePipe } from '@angular/common';

    @Component({
      selector: 'material-app',
      templateUrl: 'app.component.html',
      styleUrls: ['./app.component.css'],
      providers: [DatePipe]
    })

    transformDate(date) {
      return this.datePipe.transform(date, 'MM/dd/yyyy');
    }

    unSetAndRebuildForm() {
        if (this.formGroup.get('dateEnjoined').value == this.anotherDate) {
          this.formGroup.reset();
          // console.log(this.transformDate(this.importantDate));
          // alert(this.transformDate(this.importantDate));
          this.formGroup.patchValue({ dateEnjoined: this.transformDate(this.importantDate) });
          this.test = 0;
        } else {
          this.formGroup.reset();
          // console.log(this.transformDate(this.anotherDate));
          // alert(this.transformDate(this.anotherDate));
          this.formGroup.patchValue({ dateEnjoined: this.transformDate(this.anotherDate) });
          this.test = 1;
        }
      }

另外请从模板文件中删除 [value]。