2017-10-05 10 views
0

私はアンギュラユニバーサルで動的フォームを作成しようとしています。フォームは作成者によってフォームがどのようにデザインされたかによって、特定の質問が必須であるように設定され、その他は設定されません。ユーザーが記入するためのフォームを表示すると、Angular Universal(JiTコンパイラ、AoTコンパイラと比較して)を使わずに完全に正常に機能しました。アンギュラユニバーサル: "未定義の '_updateTreeValidity'プロパティを読み取ることができません。

フォームには、各フォームの質問に注入されるカスタムコンポーネントが含まれています。これにより、ユーザーは送信するためにコンポーネントにレスポンスを入力できます。

アプリケーションが正常にコンパイルされますが、このコンポーネントがロードされたとき、私は多くのエラーを取得:

Cannot read property '_updateTreeValidity' of undefined

Cannot read property 'setParent' of undefined at e._registerControl

ERROR Error: formGroup expects a FormGroup instance. Please pass one in.

これは、フォームのtypescriptですです:

import { Component, OnInit, ViewChild, OnDestroy, NgZone, EventEmitter } from '@angular/core'; 
import { Router, ActivatedRoute, Params } from '@angular/router'; 
import { AuthenticationService } from '../../services/authentication.service'; 
import { ProgramsService } from '../../services/programs.service'; 
import { InfoService } from '../../services/info.service'; 
import { FormGroup, FormControl, FormBuilder, Validators, FormArray } from '@angular/forms'; 
import { SessionsService } from '../../services/sessions.service'; 
import { Answers } from '../formComponents/answers'; 
import { AnswerComponent } from '../formComponents/answer.component'; 


@Component({ 
    templateUrl: './intro.component.html', 
    styleUrls: ['./intro.component.css'], 
    providers: [SessionsService, InfoService, ProgramsService] 
}) 
export class IntroComponent implements OnInit, OnDestroy{ 

    constructor(private router: Router, private route: ActivatedRoute, private _programsService: ProgramsService, private zone: NgZone, private _fb: FormBuilder, private _sessionsService: SessionsService){ 

    this.myForm = this._fb.group({ 
     questions: this._fb.array([]) 
    }); 


    this.subcribeToFormChanges(); 
    } 




    programId: string; 
    sessionId: string; 
    private sub: any; 
    res; 
    coachUsername; 
    welcomeHeader; 
    welcomeDescription; 
    welcomeFiles; 
    requiredQuestions; 
    formData: FormData; 
    public myForm: FormGroup; 
    public events: any[] = []; 
    loading; 
    introCompleted; 
    isForm = false; 



    ngOnInit() { 
    this.sub = this.route.params.subscribe(params => { 
     this.sessionId = params['id']; 
     this.getSessionInfo(this.sessionId); 
    }); 
    } 





    getSessionInfo(id){ 
    this.loading = true; 
    this._sessionsService.getSession(id).subscribe(res=>{ 
     this.loading = false; 
     console.log(res.programId); 
     this.programId = res.programId; 
     if(res.introSessionCompleted == false){ 
     this.introCompleted = false; 
     this.getForm(); 
     } 
     if(res.introSessionCompleted == true){ 
     this.introCompleted = true; 
     this.getAnswers(); 
     } 
    }) 
    } 



    getAnswers(){ 
    this._sessionsService.getAnswerIntro(this.sessionId).subscribe(res=>{ 
     console.log('session answers'); 
     console.log(res); 
     this.fillAnswers(res); 
    }) 
    } 



    fillAnswers(res){ 
    this.getFormLight(); 
    for(var i=0; i<res.questions.length; i++){ 
     this.answerQuestion(res.questions[i].type, res.questions[i].placeholder, res.questions[i].title, res.questions[i].required, res.questions[i].answer); 
    } 
    } 



    getFormLight(){ 
    this._programsService.clientGetIntro(this.programId).subscribe(res=>{ 
     console.log('Intro res:') 
     console.log(res) 
     this.welcomeDescription = res.welcomeDescription; 
     this.welcomeHeader = res.welcomeHeader; 
     this.welcomeFiles = res.welcomeFiles; 
    }) 
    } 

    getForm(){ 
    this._programsService.clientGetIntro(this.programId).subscribe(res=>{ 
     this.isForm = true; 
     console.log('Intro res:') 
     console.log(res) 
     this.res = res; 
     this.welcomeDescription = res.welcomeDescription; 
     this.welcomeHeader = res.welcomeHeader; 
     this.welcomeFiles = res.welcomeFiles; 
     this.requiredQuestions = res.requiredQuestions; 
     if(this.requiredQuestions){ 
     for(var i=0; i<this.requiredQuestions.length; i++){ 
      this.addQuestion(this.requiredQuestions[i].type, this.requiredQuestions[i].placeholder, this.requiredQuestions[i].title, this.requiredQuestions[i].required); 
     } 
     } 
    }) 
    } 



    initQuestion(type, placeholder, title, required) { 
    if(required == 'yes'){ 
     return this._fb.group({ 
     type: [type], 
     placeholder: [placeholder], 
     title: [title], 
     required: [required], 
     answer: ['', Validators.required] 
    }); 
    } 
    if(required == 'no'){ 
     return this._fb.group({ 
     type: [type], 
     placeholder: [placeholder], 
     title: [title], 
     required: [required], 
     answer: [''] 
    }); 
    } 

    } 

    initAnswerQuestion(type, placeholder, title, required, answer){ 
    return this._fb.group({ 
     type: [type], 
     placeholder: [placeholder], 
     title: [title], 
     required: [required], 
     answer: new FormControl({value: answer, disabled: true}) 
    }); 
    } 

    ngOnDestroy() { 
    this.sub.unsubscribe(); 
    } 

    save(model: Answers, isValid: boolean) { 

    this._sessionsService.answerIntro(this.programId, this.sessionId, JSON.stringify(model)).subscribe(res=>{ 
     console.log(res); 
     if(res.message == 'Finished updating answers'){ 
     this.router.navigateByUrl('/account/sessions/view/'+this.sessionId) 
     } 
    }) 
    } 

    addQuestion(type, placeholder, title, required) { 
    const control = <FormArray>this.myForm.controls['questions']; 
    const addrCtrl = this.initQuestion(type, placeholder, title, required); 
    control.push(addrCtrl); 
    } 

    answerQuestion(type, placeholder, title, required, answer) { 
    const control = <FormArray>this.myForm.controls['questions']; 
    const addrCtrl = this.initAnswerQuestion(type, placeholder, title, required, answer); 
    control.push(addrCtrl); 
    } 

    removeQuestion(i: number) { 
    const control = <FormArray>this.myForm.controls['questions']; 
    control.removeAt(i); 
    } 

    subcribeToFormChanges() { 
    const myFormStatusChanges$ = this.myForm.statusChanges; 
    const myFormValueChanges$ = this.myForm.valueChanges; 
    myFormStatusChanges$.subscribe(x => this.events.push({ event: 'STATUS_CHANGED', object: x })); 
    myFormValueChanges$.subscribe(x => this.events.push({ event: 'VALUE_CHANGED', object: x })); 
    } 

} 

これはhtmlです形式:

これは、カスタム回答コンポーネントtypescriptです

import { Component, Input, OnInit } from '@angular/core'; 
import { FormGroup } from '@angular/forms'; 

@Component({ 
    moduleId: module.id, 
    selector: 'answer', 
    templateUrl: 'answer.component.html', 
    styleUrls: ['./answer.component.css'] 
}) 
export class AnswerComponent implements OnInit { 
    @Input('group') 

    public answerForm: FormGroup; 


    type; 
    title; 
    required; 
    disabled; 

    ngOnInit(){ 
     this.type = this.answerForm.controls['type'].value; 
     this.required = this.answerForm.controls['required'].value; 
     this.title = this.answerForm.controls['title'].value; 
     if(this.answerForm.controls['answer'].value != null && this.answerForm.controls['answer'].value != ''){ 
      this.disabled = true; 

      console.log('disabled'); 
     } 
    } 





} 

最後にあり、ここで私が問題でngForオブジェクトに対する応答のいずれかを考え出し

<div [formGroup]="answerForm"> 
    <div class="form-group"> 

     <div class="left-hand"> 
      <div class="question-text"><a>{{title}}</a></div> 
     </div> 

     <div class="right-hand"> 
      <textarea *ngIf="type=='text'" class="form-answer" placeholder="Type answer here..." formControlName="answer"></textarea> 
      <input class="number" type="number" placeholder="Enter answer here..." formControlName="answer" *ngIf="type=='number'" > 
      <select *ngIf="type=='yesno'" formControlName="answer" > 
       <option value="" disabled selected>Choose answer</option> 
       <option>Yes</option> 
       <option>No</option> 
      </select> 
     </div> 


    </div> 
</div> 

答えて

0

カスタムコンポーネントhtmlです配列には空白の値が含まれていたため、コンポーネントが混乱していました。

関連する問題