NgbDatepicker以反应形式:设置初始值 [英] NgbDatepicker in Reactive Forms: Set Initial Value

查看:84
本文介绍了NgbDatepicker以反应形式:设置初始值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这可能是我一段时间以来遇到的最令人沮丧的问题之一.一般而言,日期,尤其是NgbDatepicker,在Angular中有点难以应付.

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 8中的反应形式实现NgbDatepicker,而我的问题的要点是我可以设置日期控件的初始值,但是该初始值不会(直观地)显示在表单上.我可以将表单登录到控制台,并看到该值已设置,但是表单字段本身未更新.如果我从选择器本身中选择一个日期,那么我的选择将反映在表单字段中.我以为它就像设置ngbDatepicker输入的 [startDate] 属性一样简单,但显然没有.我对此进行了很多不同的迭代.这就是代码所代表的地方:

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. 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. I had thought it would be as simple as setting the [startDate] property of the ngbDatepicker input, but apparently no. I've tried a lot of different iterations on this; here's where things stand, code-wise:

我的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">

组件的相关位:

@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 };
  }
}

以上HTML驻留在该CertForm类型指定的formGroup中.该表单包含日期控件,看起来(部分)如下:

The above HTML resides in a formGroup that is spec'd by that CertForm type. 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;
  }
}

从那里开始,我有一个自定义的解析器/格式器设置,看起来就像NGB示例页面上指定的那样:

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:

@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.

我尝试了很多不同的想法组合,但没有任何效果.真令人沮丧.我看到这个问题的变体/片段确实已经存在,但是我找不到通过这种技术组合来问这个问题的例子.使用NgbDatepicker时,大多数人似乎都是依靠模板形式,而不是反应形式.

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.

推荐答案

startDatae 属性未设置初始值.您应该将formControl的值设置为所需的值.

startDatae property on the date picker does not set the initial value. You should set your formControl's value to be the value you want.

这是一个没有解析器的示例.我在工作时使用了自定义解析器/格式化程序,尽管它确实可以工作(无法在此处发布该代码).

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).

正在工作的stackblitz(请注意,这是在最新的Angular和NgBootstrap上发布的) https://stackblitz.com/edit/angular-zpeul4

Working stackblitz (note this is on latest Angular and NgBootstrap) https://stackblitz.com/edit/angular-zpeul4

应用程序组件

  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);
  }

模板

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

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

</div>  

如果解析器仍然存在问题,请确保同时具有 NgbDateParserFormatter NgbDateAdapter ,并且将其设置为的初始值可以正确转换通过适配器(如果它不是Ngb日期对象)

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)

这篇关于NgbDatepicker以反应形式:设置初始值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆