双向服务不更新Angular 2

时间:2017-10-06 02:06:06

标签: angular angular2-services

我正在努力让双向服务工作,无法弄清楚我错过了哪一步或者做错了什么。控制台中没有错误,但当我尝试发送数据时没有任何反应通过它。(Here's)是我迄今所拥有的东西。

我想要完成的过程就像这样

将此数据体加载到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.

创建服务以从Response中的input.component.ts变量接收数据,并使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);
    }

}

FormList中创建对app.ts的订阅。 (成功完成)

//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 个答案:

答案 0 :(得分: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的{​​{1}}不正确,我建议您使用official example中的此方法。

您的服务应如下所示。

FormList

现在在你的@Injectable() export class AnswerService { private _formList = new Subject<any>(); public FormList = this._formList.asObservable(); addResponse(event: FormResponse){ this._formList.next(event); } } 上你需要订阅这样的事件:

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代码可能需要一些修改,但你明白了。

这是一个plunker工作!