首页 文章

Angular 2将表单数据传递给另一个组件

提问于
浏览
2

我有一个允许用户创建帐户的表单,一旦用户点击提交按钮,用户就会导航到另一个页面,其中包含他们创建的帐户的详细信息 . 我遇到的问题是将该对象传递给详细信息视图 .

例如,这是表单的组件,

import {Component, OnInit, OnDestroy, Input} from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import {Customer} from "../model/customer";
import {Router } from '@angular/router';
import {CustomerService} from "../service/customer.service";
import {CustomerProfileComponent} from "../customer-profile/customer-profile.component";

@Component({
  selector: 'app-new-customer',
  templateUrl: './new-customer.component.html',
  styleUrls: ['./new-customer.component.css']
})
export class NewCustomerComponent implements OnInit {

  @Input() customer: Customer;

  //this is only dev data do not use this in prod
  private countries = [];
  private customerSources = [];
  private secondarySources =[];

  //Create the forum group
  public newCustomerForm: FormGroup;
  public submitted: boolean; // keep track on whether form is submitted

  constructor(private fb: FormBuilder, public customerService: CustomerService,private router: Router) {

    this.countries = [
      {value:'UK'},
      {value:'Germany'},
      {value:'Turkey'},
      {value:'Italy'}
      ];

    this.customerSources = [
      {value: 'Through a friend or colleague (not a Client)'},
      {value: 'Through an existing Client'},
      {value: 'Direct Sales (e.g. cold call, direct mail, email)'},
      {value: 'Web Search e.g. Google'}
    ];

    this.secondarySources = [
      {value: '1st Hire'},
      {value: 'A Test Client With A Long Business Name'},
      {value: 'Abbigail West'}
    ];
  }

  ngOnInit() {
    this.newCustomerForm = this.fb.group({
      id:[''],
      company_name: ['', [<any>Validators.required, <any>Validators.minLength(5)]],
      vat:[''],
      address:[''],
      country:[''],
      first_name:[''],
      surname:[''],
      phone:[''],
      email:['',[<any>Validators.required, <any>Validators.minLength(5)]],
      customer_sources:[''],
      secondary_sources:['']
    });
  }

这是我的表格html,

<form [formGroup]="newCustomerForm" novalidate (ngSubmit)="saveNewCustomer(newCustomerForm.value, newCustomerForm.valid)">
    <section>
      <aside>
        <p>Once you've added your new <b>Client</b>, you can come back and allow them access to view their <b>Invoices</b> &amp; <b>Payments</b> - they can also make <b>Payments</b> via Paypal if you have it enabled.</p>
      </aside>


      <input type="hidden" name="id"  formControlName="id"/>

      <h4>New Client Details</h4>
      <md-input-container>
        <input mdInput type="text" name="company_name" placeholder="Customer Name" formControlName="company_name" />
        <small [hidden]="newCustomerForm.controls.company_name.valid || (newCustomerForm.controls.company_name.pristine && !submitted)">
          Customer Name is required (minimum 5 characters).
        </small>
      </md-input-container>

      <md-input-container>
        <input mdInput type="text" name="vat"  placeholder="VAT Number" formControlName="vat"/>
      </md-input-container>

      <md-input-container>
        <input mdInput type="text" name="address"  placeholder="Address" formControlName="address" />
      </md-input-container>

      <md-select placeholder="Country" name="country" formControlName="country" >
        <md-option *ngFor="let country of countries" [value]="country.value" >
          {{country.value}}
        </md-option>
      </md-select>

      <h4>Your Primary Contact</h4>
      <div class="left-column">
        <md-input-container>
          <input mdInput type="text" name="first_name"  placeholder="First Name" formControlName="first_name" />
        </md-input-container>
      </div>

      <div class="left-column">
        <md-input-container>
          <input mdInput type="text" name="surname"  placeholder="surname" formControlName="surname" />
        </md-input-container>
      </div>

      <div class="clearfix"></div>

      <div class="left-column">
        <div class="left-column">
          <md-input-container>
            <input mdInput type="text" name="phone"  placeholder="Phone" formControlName="phone"/>
          </md-input-container>
        </div>
      </div>

      <div class="right-column">
        <div class="left-column">
          <md-input-container>
            <input mdInput type="text" name="email"  placeholder="Email" formControlName="email"/>
            <small [hidden]="newCustomerForm.controls.email.valid || (newCustomerForm.controls.email.pristine && !submitted)">
              Email is required (minimum 5 characters).
            </small>
          </md-input-container>
        </div>
      </div>

      <div class="clearfix"></div>
      <h4>Customer Source</h4>
      <div class="left-column">
        <md-select placeholder="How were you introduced to this Client?" formControlName="customer_sources">
          <md-option *ngFor="let cs of customerSources" [value]="cs.value" >
            {{cs.value}}
          </md-option>
        </md-select>
      </div>

      <div class="right-column">
          <md-select placeholder="Which Client introduced you?" formControlName="secondary_sources">
            <md-option *ngFor="let ss of secondarySources" [value]="ss.value" >
              {{ss.value}}
            </md-option>
          </md-select>
      </div>
      <div class="clearfix"></div>
    </section>

    <aside>
      <div class="right-aside">
        <button type="submit" class="cancel">Cancel</button>
        <button type="submit" class="save">Save</button>
      </div>
      <div class="clearfix"></div>
    </aside>
    </form>

客户服务在我的app.module中 . 在这里,我保存数据并将用户移动到新页面 .

saveNewCustomer(customer: Customer, isValid: boolean){
    if(isValid){
      this.submitted = true; // set form submit to true
      this.customerService.saveNewCustomer(customer)
        .subscribe(
          res => this.customer,
          error => console.log(<any>error)
        );

      this.router.navigateByUrl('/earning/customers/profile');
    }
  }


}

这是我希望客户对象使用的组件,因此它存在于视图中 .

import {Component, OnInit, Input} from '@angular/core';
import {Customer} from "../model/customer";
import {NewCustomerComponent} from "../new-customer/new-customer.component";

@Component({
  selector: 'app-customer-profile',
  templateUrl: './customer-profile.component.html',
  styleUrls: ['./customer-profile.component.css'],
  providers:[NewCustomerComponent]
})
export class CustomerProfileComponent implements OnInit {

 @Input() customer: Customer;

  constructor() {
    console.log(this.customer);
  }

  ngOnInit() {
  }

}

<main>
  <header>
    <h4>&nbsp;</h4>
    <h1><strong><i></i>Customer profile</strong></h1>
    </header>
  <article>
    <section>
      <p></p>

      <p>
        {{customer}}
      </p>
      </section>
    </article>
  </main>

但客户在CustomerProfileComponent中未定义 . 我不确定我做错了什么 . 如果有人能指出我正确的方向将非常感激 .

Update to include service class based on suggestion

import { Injectable } from '@angular/core';
import {Http, Response, Headers, RequestOptions} from '@angular/http';
import {CookieService} from "angular2-cookie/services/cookies.service";

import {Observable, Subject} from "rxjs";
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import {Customer} from "../model/customer";


@Injectable()
export class CustomerService {

  private csrfToken;
  private newCustomerUrl = "/earning/customers/new";
  private customer = new Subject<Object>();

  customer$ = this.customer.asObservable();

  constructor(public http: Http, private cookieService: CookieService) {
    this.getCsrfToken();
  }

  getCsrfToken(){
    this.csrfToken = this.cookieService.get("PLAY_SESSION").substring(this.cookieService.get("PLAY_SESSION").indexOf("csrfToken"));
  }

  saveNewCustomer(customer:Customer): Observable<Customer>{

    let headers = new Headers({
      'Content-Type':'application/json'
    });

    let options = new RequestOptions({ headers: headers });

    return this.http.post(this.newCustomerUrl+"?"+this.csrfToken, customer, options) // ...using post request
      .map((res:Response) => res.json()) // ...and calling .json() on the response to return data
      .catch(this.handleError); //...errors if any
  }

  private handleError (error: Response) {
    return Observable.throw('Internal server error: ' + error);
  }

  emitCustomer(customer) {
    this.customer.next(customer);
  }


}

1 回答

  • 1

    如上所述,共享服务将是一个不错的选择 . 以下示例通过服务在组件之间共享Object:

    您的服务:

    public sharedCustomer = {};
    

    然后,组件在您从api收到客户后,将客户推送到服务部门:

    this.customerService.saveNewCustomer(customer)
        .subscribe(res => {
           this.customer = res;
           this.customerService.sharedCustomer = this.customer;
           this.router.navigateByUrl('/earning/customers/profile');
        });
      }
    

    请注意,我在订阅和导航中发布了客户,以确保客户正确地存储在服务中,以及在此之前不从页面导航 .

    然后在您的详细页面中:

    ngOnInit() {
      this.customer = this.customerService.sharedCustomer;
    }
    

相关问题