简体   繁体   English

Reactive 中的 NgbDatepicker Forms:设置初始值

[英]NgbDatepicker in Reactive Forms: Set Initial Value

This might be one of the more frustrating issues I've coped with in a while.这可能是我一段时间以来处理过的最令人沮丧的问题之一。 Dates and -- in particular -- NgbDatepicker are a bit of a bear to deal with in Angular, in general.一般来说,在 Angular 中处理日期,尤其是 NgbDatepicker 有点麻烦。

I'm implementing NgbDatepicker against reactive forms in Angular 8, and the gist of my problem is that I can set the initial value of my date control, but that initial value doesn't show-up (visually) on the form.我正在针对 Angular 8 中的反应式 forms 实施 NgbDatepicker,我的问题的要点是我可以设置我的日期控件的初始值,但该初始值不会(在视觉上)显示在表单上。 I can log my form to the console and see that the value is getting set, but the form field itself doesn't update.我可以将我的表单记录到控制台并看到值正在设置,但表单字段本身不会更新。 If I select a date from the picker itself then my selection reflects in the form field.如果我 select 来自选择器本身的日期,那么我的选择会反映在表单字段中。 I had thought it would be as simple as setting the [startDate] property of the ngbDatepicker input, but apparently no.我原以为它会像设置 ngbDatepicker 输入的[startDate]属性一样简单,但显然没有。 I've tried a lot of different iterations on this;我已经尝试了很多不同的迭代; here's where things stand, code-wise:这是事情的立场,代码方面:

My HTML:我的HTML:

<input #licenseExpiration="ngbDatepicker"
    class="form-control"
    fromControlName="licenseExpiration"
    [startDate]="startDate"
    ngbDatepicker />
<button class="btn btn-info zero-spacing pt-1 pr-1 pl-1"
    (click)="licenseExpiration.toggle()"
    type="button">

The relevant bits of my component:我组件的相关部分:

@Component({
  selector: 'app-cert',
  templateUrl: './cert.component.html',
  providers: [
    { provide: NgbDateParserFormatter, useClass: CustomDateParserFormatter }
  ]
})
export class CertComponent implements OnInit {
  certForm: CertForm = new CertForm();

  constructor(
    public readonly formatter: CustomDateParserFormatter) { }

  ngOnInit() {
    this.certForm.setModel(...modelObjectFromOtherService...);
  }

  get startDate() {
    return { year: 2020, month: 6, day: 13 };
  }
}

The above HTML resides in a formGroup that is spec'd by that CertForm type.上面的 HTML 驻留在由该 CertForm 类型指定的 formGroup 中。 That form contains the control for the date and looks (in part) like this:该表单包含日期控件,看起来(部分)如下所示:

export class CertForm extends FormGroup {
  public dateParser: CustomDateParserFormatter;

  constructor(
    cert: ICertModel = new CertModel()) {
    super({
      ..
      licenseExpiration: new FormControl("", Validators.required),
      ..
    });
  }

  setModel(cert: ICertModel) {
    this.patchValue({
      licenseExpiration
    });
  }

  getModel(): ICertModel {
    const cert = new CertModel();
    ...
    cert.licenseExpiration = this.get("licenseExpiration").value;
    ...
    return cert;
  }
}

From there I do have the custom parser/formatter set-up and it looks just like the one that is spec'd on the NGB examples pages:从那里我确实有自定义解析器/格式化程序设置,它看起来就像 NGB 示例页面上指定的那样:

@Injectable({
  providedIn: "root"
})
export class CustomDateParserFormatter extends NgbDateParserFormatter {

  readonly DELIMITER = '/';

  parse(value: string): NgbDateStruct | null {
    if (value) {
      let date = value.split(this.DELIMITER);
      return {
        day: parseInt(date[0], 10),
        month: parseInt(date[1], 10),
        year: parseInt(date[2], 10)
      };
    }
    return null;
  }

  format(date: NgbDateStruct | null): string {
    return date ? date.month + this.DELIMITER + date.day + this.DELIMITER + date.year : '';
  }
}

And, again, this just won't seem to let me initiate that date field with a visible start-up value.而且,这似乎不会让我启动具有可见启动值的日期字段。 As you can see, at this point I'm just literally hard-coding a return value for that start date.如您所见,此时我只是硬编码该开始日期的返回值。 And that date does get properly set -- when you open the picker, that's the date it lands on, but it doesn't actually show-up in the display field when you land on the page.那个日期确实设置正确——当你打开选择器时,这是它登陆的日期,但当你登陆页面时它实际上并没有出现在显示字段中。 That's just blank until you actually select a value.在您实际 select 一个值之前,这只是空白。

I have attempted so many different combinations of ideas and nothing is working.我尝试了很多不同的想法组合,但没有任何效果。 It's incredibly frustrating.真是令人沮丧。 I see that variations/fragments of this question do exist already, but I can't find examples of the question being asked with quite this combination of technologies.我看到这个问题的变体/片段确实已经存在,但是我找不到使用这种技术组合提出的问题的例子。 Most people seem to be relying on templated forms, not reactive forms, when using NgbDatepicker.大多数人在使用 NgbDatepicker 时似乎依赖于模板化的 forms,而不是反应式的 forms。

startDatae property on the date picker does not set the initial value.日期选择器上的startDatae属性未设置初始值。 You should set your formControl's value to be the value you want.您应该将 formControl 的值设置为您想要的值。

This is an example without the parser.这是一个没有解析器的例子。 I use a custom parser/formatter at work and it does work though (can't post that code here).我在工作中使用自定义解析器/格式化程序,但它确实有效(不能在此处发布该代码)。

Working stackblitz (note this is on latest Angular and NgBootstrap) https://stackblitz.com/edit/angular-zpeul4工作 stackblitz(注意这是最新的 Angular 和 NgBootstrap) https://stackblitz.com/edit/angular-zpeul4

App Component应用组件

  formGroup = new FormGroup({});

  ngOnInit() {
    console.log('on init');
    this.formGroup.addControl("test", new FormControl({day: 20, month:4, year:1969})) //nice
    this.formGroup.valueChanges.subscribe(val => {
      console.log(val);
    })
    console.log(this.formGroup.value);
  }

Template模板

 <div class="container" [formGroup]="formGroup">
    
  <input #licenseExpiration="ngbDatepicker"
    class="form-control"
    [formControlName]="'test'"
    ngbDatepicker />

  <button class=""
  (click)="licenseExpiration.toggle()"
  type="button">open</button>

</div>  

If you are still having issues with your parser, make sure you have both an NgbDateParserFormatter and NgbDateAdapter and that your initial value you are setting it to can get converted properly by the adapter (if its not an Ngb Date Object)如果您的解析器仍然存在问题,请确保您同时拥有NgbDateParserFormatterNgbDateAdapter ,并且您设置的初始值可以被适配器正确转换(如果它不是 Ngb 日期对象)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM