Реактивная форма: как размыть и отправить в один клик - PullRequest
1 голос
/ 16 октября 2019

У меня есть Реактивная форма (#myform) с кнопкой "foo", к которой прикреплена (click) = myform.submit(), так что форма будет отправляться только при нажатии этой кнопки, а не при событиях Enter. Компонент прослушивает Enter события и отправляет blur в этом случае, и все FormControls имеют {updateOn: 'blur'}, поэтому blur события запускают обновления (т. Е. valueChanges и т. Д.).

Myпроблема заключается в следующем: если я ввожу данные в Input (или выбираю элемент в Select), не нажимая Enter или Tabbing из элемента, а затем нажимаю "foo", то есть "Submit"Похоже, что нажатие кнопки "foo" вызывает только событие blur без запуска отправки формы (через myform.submit). То есть, submit «проглатывается» событием blur.

Как я могу настроить это так, чтобы, если я не Enter или Tab вне элемента, и немедленнонажмите "foo", элемент будет обновлен с помощью события blur И ТОЛЬКО форма будет также отправлена?

Я пробовал такие вещи, как: 1. сначала обработать blur, а затем попробоватьпрограммный вызов myform.submit() в компоненте (путем доступа от Form до @ViewChild) и 2. добавление прослушивателя (blur)= (submitNow && setTimeout(()=>myform.submit(),50) в представлении шаблона. На данный момент у меня даже нет этого setTimeout вызова для компиляции, и ни один из подходов, которые я пробовал, кажется, пока не работает.

Исходный код (упрощенный) выглядит так: шаблон details.component.html


<form #myform [formGroup]="form" method="POST" action="http://localhost:3000/users/{{userID}}/details">
        <ng-container *ngFor="let sec of datArr">
                <ng-container *ngFor="let row of sec; let i = index">
                          <input type="text"
                          [appTag]="row[datColEnum.tabCol]"
                          (keydown.enter)="onEnter($event)"
                          tabindex = "{{row[datColEnum.tabCol]}}"
                          name="{{row[datColEnum.controlNameCol]}}" value="{{row[datColEnum.valueCol]}}" 
                          formControlName="{{row[datColEnum.controlNameCol]}}"/>
                </ng-container>
         </ng-container>
  <button name="foo" type="button" (click)="myform.submit()">Submit</button>
</form>


компонент details.component.ts

export class DetailsComponent implements OnInit, AfterViewInit {
@ViewChildren(TagDirective) ipt!: QueryList<ElementRef>;
@ViewChild('myform', {static: true}) myform: any;

data: Object;
meta: Object;
datArr: any[] = [];
formCtls: any = {};
form: FormGroup = new FormGroup({});
tabIdx: number = 0;
focusItm: number = 0;
submitNow: boolean = false;

  constructor(private member: MemberService, private route: ActivatedRoute, private el: ElementRef) { }

  ngAfterViewInit() {
    this.ipt.changes.subscribe(list=>{
      setTimeout(()=>
        list.filter(itm=>+itm.id===this.focusItm%this.tabIdx).forEach(itm=>{
          if (!this.first_pass) this.navigateTo(itm.id);
        }  
      ),100)
    })
  }

  doSubmit() {
    this.submitNow = true;
  }

  navigateTo(ti: number) {
    console.log(`NAVIGATING TO ITEM WITH TAB INDEX: ${ti}`)
    this.ipt["_results"][ti-1].el.nativeElement.focus();
    this.ipt["_results"][ti-1].el.nativeElement.style.borderWidth = "3px";
  }

  onEnter(e: Event) {

    let cname = (<HTMLInputElement | HTMLSelectElement>e.target).name;
    let idx = 0;
    for (let itm of this.ipt["_results"]) {
      if (itm.el.nativeElement.name === cname) {
        this.focusItm = (itm.id+1)%this.ipt["_results"].length;
        itm.el.nativeElement.style.borderWidth = "1px";
        break;
      }
    }
    e.target.dispatchEvent(new Event('blur'));

  }

  ngOnInit() {
 . . . 
 . . . 

//SET EVERYTHING UP

      this.renderDataArray();
. . . 
. . .

     })

  };

// SET UP ALL THE FormControls, etc. AND THE DATA MODEL datArr USED TO RENDER THE TEMPLATE
  renderDataArray() {
    this.datArr = [];
    this.tabIdx = 0;
    Object.keys(this.meta).forEach((sec,idx) => {
          let rowCnt = this.getActiveArrayLen(sec);
          for (let i = 0; i < rowCnt; i++) {
            Object.keys(this.data[sec]).
              .map((fld,idx)=>{
              let itm = this.data[sec][fld];
                      this.tabIdx += 1;
                      let val =  getVal();
                      let ctlName = sec+this.FLD_SPLIT_CHAR+fld; 
                      this.removeControl(ctlName);
                      this.formCtls[ctlName] = new FormControl(val, {updateOn: 'blur'});
                      this.form.addControl(ctlName, this.formCtls[ctlName]);
                      of(this.tabIdx).
                        pipe(switchMap(ti=>this.formCtls[ctlName].valueChanges.
                          pipe(map(newVal => [newVal,ti]))
                          )
                        ).subscribe(([newVal,ti])=>{
                            if (Array.isArray(itm["value"])) {
                              itm["value"][+(itm["value"].length || 1)-1]=newVal || '';
                            } else {
                              itm["value"]=newVal || '';
                            }
                          this.focusItm = (ti+1)%this.ipt["_results"].length;
                          this.renderDataArray();
                        });
. . . 
. . . 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...