2017-03-03 84 views
2

我有一个允许用户创建一个帐户的表单,一旦用户点击提交按钮,用户将被导航到另一个页面,并带有他们创建的帐户的详细信息。我遇到的问题是将该对象传递给细节视图。Angular 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> 

但Customer在CustomerProfileComponent中未定义。我不确定我做错了什么。如果任何人能指出我在正确的方向将非常感激。

更新包括基于建议

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


} 
+0

后的相关模板代码 –

+0

要么粘贴'html'代码,或设置的组件之间的通信的服务这里显示:https://angular.io /docs/ts/latest/cookbook/component-communication.html#!#bidirectional-service –

+0

@AvinashRaj我粘贴了我的html代码。谢谢 –

回答

1

如前所述共享服务将是一个不错的选择服务类。下面的例子是通过服务共享对象的组件之间:

您的服务:

public sharedCustomer = {}; 

和组件,之后你收到客户从API,推动客户服务:

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

注意到,我发射了客户认购,以及导航,以确保客户得到的服务中存储不当,以及没有导航离开˚F在此之前的页面。

然后在您的详细信息页面:

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

我似乎越来越不确定,我的个人资料页上 'ngOnInit(){ this.customerService.customer $ .subscribe(客户=> { this.customer =客户; }); console.log(this.customer); }' 有从客户对象类型的API返回的数据 –

+0

我也更新了我的问题以包含我的服务类。 –

+0

您是否检查过您的订阅确实收到了客户,它是否未定义?:) – Alex

相关问题