2017-10-06 90 views
0

我試圖讓雙向服務工作,但無法弄清楚我在哪裏錯過了一個步驟,或者做了什麼錯誤。在控制檯中沒有錯誤當我試圖通過它來發送數據卻什麼也沒有發生。(Here's)一plunker什麼,我有這麼遠。Angular 2中沒有更新數據的雙向服務

我試圖完成的過程是這樣的

加載該機構的數據爲app.ts並與input.copmonent.ts重複。(成功完成)

{ 
    "questions":[ 
     { 
     "question": "How tall are you?", 
     "name": "height", 
     "id": "heightCtrl", 
     "template": "smInput" 
     }, 
     { 
     "question": "What is your favorite color?", 
     "name": "color", 
     "id": "colorCtrl", 
     "template": "smInput" 
     }, 
     { 
     "question": "What kind of car do you drive?", 
     "name": "car", 
     "id": "carCtrl", 
     "template": "smInput" 
     } 

    ] 
} 

將數據加載到新變量並在模板中使用ngModel來更新用戶響應。 (成功完成)

//Input Component (omitted for relevance) 

@Component({ 
    template:` 
      <ng-container *ngIf="Qdata.template == 'smInput'"> 


       <p>{{Qdata.question}}</p> 

       <input type="text" 
        id="Qdata.id" 
        name="Qdata.name" 
        [(ngModel)]="Response.response" 
       > 


      </ng-container> 
      ` 
}) 

export class InputComponent implements OnInit{  

    @Input() Qdata: any;  //from app.ts 

    Response: FormResponse={}; // new variable 

    ngOnInit(){ this.prepResponse(); } 

    prepResponse(){ 
     let a = this.Qdata; 
     let b = this.Response; 

     b.question = a.question; 
     b.id = a.id; 
     b.name = a.name; 
    } 
} 



// Note: FormResponse is a custom class I made that's shaped the same as 
// the json data with the addition of a "response:string='';" field. 

創建服務於input.component.tsResponse變量接收數據並提供一些app.ts訂閱。 (做成功....我想...在大多數情況下)

//Imports Observable and Subject from proper places 

@Injectable() 

export class AnswerService { 

    private FormList = new Subject<FormResponse[]>(); // so far I think this is contributing 
                 to the problem somehow. 

    addResponse(data:FormResponse){ 
    this.FormList.next(data); 
    } 

    getFormList(): Observable<FormResponse[]>{ 
    return this.FormList.asObservable(); 
    } 

} 

Input.component.ts創建功能將數據發送到addResponse()功能服務。 (做成功....我想)

import { AnswerService } from './answer.service'; 

@Component({ 
    template:` 
     <ng-container *ngIf="Qdata.template == 'smInput'"> 
      <!--previous HTML --> 

      <button (click)="sendResponse()">send</button> 
      <!-- plan to ultimately use OnChanges, using this to test --> 

     </ng-container> 
     `, 
    providers: [AnswerService] 
}) 

export class InputComponent implements OnInit{  

    @Input() Qdata: any; 

    Response: FormResponse={}; 


    constructor(private _ans : AnswerService) {} 

    ngOnInit(){ ... } prepResponse(){...} 

    sendResponse(): void{ 
     let a = this.Response; 
     let grp = new FormResponse({ 
      question:a.question, 
      response:a.response, 
      id:a.id, 
      name:a.name 
     }); 

     this._ans.addResponse(grp); 
    } 

} 

app.ts創建訂閱FormList。 (成功完成)

//app.ts (omitted for relevance) 

import { AnswerService } from './answer.service'; 

@Component({ 
    providers: [ AnswerService ] 
}) 

export class App implements OnInit{ 

    FormData: Array<FormResponse>=[]; 

    constructor(private _ans : AnswerService){} 

    ngOnInit(){ 
     this._ans.getFormList().subscribe(list => { list = this.FormData; }); 
    } 
} 

了達到這一點的一切加載罰款沒有任何錯誤後,但是當我鍵入輸入字段的東西,並點擊發送,沒有在結合我在app.ts模板所做顯示顯示向上當一個新的對象被添加到數組中時。當我嘗試不同的方法,如push()而不是next()我得到錯誤告訴我this.FormList.push() is not a function。我需要做些什麼來實現這個目標?

我也想指出,我在input.copmonent.ts文件中「複製數據」的原因是因爲在現實世界中,這個Qdata變量的用法不止有4個屬性,儘管它只會將這4個發送到Response變量以發送回父組件。

從這點轉發我打算使用FormData變量來迭代採用隱藏式預填充輸入這樣的事情

<form #myForm="ngForm"> 

    <div *ngFor="let a of FormData"> 

     <div [attr.data-blank]="a.id" class="form-group"> 
     <!-- To force Angular to iterate a wrapper for each group --> 

      <input type="hidden" class="form-control" 
       [attr.name]="a.id" [(ngModel)]="a.question" 
      > 

      <input type="hidden" class="form-control" 
       [attr.name]="a.name" [(ngModel)]="a.response" 
      > 
     </div> 

    </div> 

</form> 

我試圖做這種方式是因爲該原因,模板驅動形式我製作的調查問卷的類型有多個嵌套在多層的問題中的可選問題which you can see here。我希望這將是收集用戶答案的​​好方法,並將它們全部放在一個地方,而不會令人頭疼。只要將answer.service導入到input.component中,無論用戶使用何種方向,以及需要什麼輸入情況,都將始終能夠發送/更新列表。我需要做些什麼來確保answer.service可以提供這種用途?

回答

1

這裏有幾個問題,第一個問題是您child component也萎靡不振的answer service作爲供應商,所以它得到AnswerService的新實例,而不是讓服務爲母公司的同一個實例的。

@Component({ 
    selector: 'input-component', 
    templateUrl: 'src/input.component.html' 
    // No providers 
}) 
export class InputComponent implements OnInit{ 

    // ... 

    /** Gets same instance of AnswerService as the parent component */ 
    constructor(private _ans: AnswerService){} 

    sendResponse(): void{ 
    this._ans.addResponse(this.Response); 
    }  
} 

此外,getter爲您FormList是不正確的,我建議使用這種方法作爲official example

你的服務應該是這樣的。

現在您app.component你需要訂閱的事件,像這樣:

@Component({ 
    selector: 'my-app', 
    templateUrl:'src/app.html', 
    providers: [ QuestionService, AnswerService ] 
}) 
export class App implements OnInit{ 

    FormData: FormResponse[] = []; 

    // ... 

    answerSubscription = this._ans.FormList.subscribe(a => { 
    console.log('gets here '+JSON.stringify(a, null, '\t')) 
    this.FormData.push(a) 
    }) 

    // ... 
} 

注意的是,在訂閱我追加結果到FormData陣列。 QuestionService代碼可能需要一些修改,但你明白了。

這是plunker工作!

+1

是的這個作品!唯一的問題是我不明白爲什麼數據沒有通過對象傳遞。 – Optiq

+1

已修復,問題出在'sendResponse'方法中,我會更新答案。搶劫者有一個工作修理。 –

+0

謝謝,我真的很感激。現在理解爲什麼這個作品大聲笑。 – Optiq