2017-03-03 116 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

相關問題