Angular 在没有回发的情况下在子组件中捕获和提交响应式表单数据

Angular Capure and Submit Reactive form data in Child Component without postback

我有一个父组件和一个子组件。我的子组件具有反应形式。我想从子表单中获取一些输入并提交。但是,只要表单位于子组件内(而不是仅位于父组件内),提交函数就会执行 postback。如果完全相同的组件是独立的而不是另一个组件的子组件,则它可以正常工作。我对 angular 有点陌生,所以我觉得有一些我不知道的标准方法可以实现这一点。

我的项目是一个angular离子项目,但这应该与它无关。此外,我最初尝试将此子组件 (AdditemComponent) 用作离子模态,但我遇到了同样的问题,其中表单 post 正在对查询字符串执行 post 返回,而不仅仅是调用onSave 方法。

我的目标是抓取子组件中的数据,并在子组件中处理并提交数据。这样我就可以把它放在我需要的地方。

Parent.ts:

import { Component, OnInit, Input } from '@angular/core';
import { AdditemComponent } from 'src/app/competitions/additem/additem.component'

@Component({
  selector: 'app-settings',
  templateUrl: './settings.page.html',
  styleUrls: ['./settings.page.scss'],
})
export class SettingsPage implements OnInit {

  constructor(){ }

  ngOnInit(){ }

}

Parent.html

<ion-header>
  <ion-toolbar>
    <ion-title class="ion-text-center">Settings</ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <app-additem></app-additem>  
</ion-content>

Child.ts

import { Component, OnInit, Input } from '@angular/core';
import { ModalController } from '@ionic/angular';
import { FormGroup, FormBuilder } from '@angular/forms';


@Component({
  selector: 'app-additem',
  templateUrl: './additem.component.html',
  styleUrls: ['./additem.component.scss'],
})
export class AddplayerComponent implements OnInit {

  @Input() selectedResult;
  private newItemForm : FormGroup;
  private teams:[];

  constructor(
    private modalCtrl: ModalController,
    private formBuilder: FormBuilder,
    private dataservice
  ) { 
    this.newItemForm = this.formBuilder.group({
      fname: [''],
      lname: [''],
      shortname: [''],
      team: ['']
    })
  }


  ngOnInit() {
  }

  onSave() {
    console.log('captured form data', this.newItemForm);
  }

  onCancel() {
    this.modalCtrl.dismiss(null, 'cancel');
  }

}

Child.html

<ion-item class="header">
  <p>Add New Item</p>
</ion-item>

<form [formGroup]="newItemForm" (ngSubmit)="onSave()">
  <ion-item>
    <ion-label>First Name</ion-label>
    <ion-input type="text" formControlName="fname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Last Name</ion-label>
    <ion-input formControlName="lname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Short Name</ion-label>
    <ion-input formControlName="shortname"></ion-input>
  </ion-item>
  <ion-item>
    <ion-label>Team</ion-label>
    <ion-select formControlName="item">
      <ion-item *ngFor="let item of items">
        <ion-select-option [value]="item.itemId">{{item.itemName}}</ion-select-option>
      </ion-item>
    </ion-select>
  </ion-item>
  <ion-item>
    <ion-button color="primary" type="submit" [disabled]="!newItemForm.valid">Submit</ion-button>
    <ion-button color="danger" (click)="onCancel()">Cancel</ion-button>
  </ion-item>
</form>

这样试试

parent.component.html

 <app-child (onsave)="saveInParent($event)"></app-child>

parent.component.ts

saveInParent(event) {
   console.log(event);
}

child.component.html

<div style="margin: 10px 20px;">
  <form [formGroup]="childForm">
    <input type="text" formControlName="email" placeholder="email"/>
    <div class="error" *ngIf="childForm.controls['email'].hasError('required') && childForm.controls['email'].touched">Email required.</div>
    <div class="error" *ngIf="childForm.controls['email'].hasError('required') && isSubmited">Email required.</div>
    <br/>
    <br/>
    <input type="password" formControlName="password" placeholder="password"/>
    <div class="error" *ngIf="childForm.controls['password'].hasError('required') && childForm.controls['password'].touched">Password required.</div>
    <div class="error" *ngIf="childForm.controls['password'].hasError('required') && isSubmited">Password required.</div>
    <br/>
    <br/>
    <button (click)="save()">Save</button>
</form>

child.component.ts

import { Component, OnInit, Output, EventEmitter } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'app-child',
  templateUrl: './child.component.html',
  styleUrls: ['./child.component.css']
})
export class ChildComponent implements OnInit {
  isSubmited = false;
  childForm: FormGroup;
  constructor(private fb: FormBuilder) { }
  @Output() public onsave = new EventEmitter();
  ngOnInit() {
    this.initForm();
  }
  initForm(){
    this.childForm = this.fb.group({
      email: ['', [Validators.required]],
      password: ['', [Validators.required]],
    });
  }
  save() {
    this.isSubmited = true;
    if (this.childForm.valid) {
      this.onsave.emit(this.childForm.value);
    }
  }

}