2017-10-06 86 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