Angular 2服务& Formbuilder:使用服务返回的值填充表单

时间:2016-02-10 00:11:39

标签: typescript angular

会爱一点帮助。

我正在试图弄清楚如何使用Formbuilder组内部服务订阅中定义的变量。

我在我的服务订阅中定义this.note

noteService.getNote(this.id)
    .subscribe((res: Response) =>{
       // this.note is defined here and works fine in my @View template decoration
       this.note = new Note(res.note.title, res.note.body, res.note.subject_id, res.note.created_at, res.note.updated_at)
  })

我在我的Formbuilder声明中引用它:

 this.noteForm = fb.group({
     title: [this.note.title, Validators.required]
 })

如何让this.note可用于Formbuilder声明?我目前收到以下错误:

EXCEPTION: TypeError: Cannot read property 'validator' of undefined in [noteForm in NoteComponent@1:14]BrowserDomAdapter.logError @ angular2.dev.js:23514BrowserDomAdapter.logGroup @ angular2.dev.js:23525ExceptionHandler.call @ angular2.dev.js:1145(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:142(anonymous function) @ angular2.dev.js:5719NgZone.run @ angular2.dev.js:5681(anonymous function) @ angular2.dev.js:14884schedulerFn @ angular2.dev.js:14385tryCatcher @ Rx.js:31Subscriber.next @ Rx.js:9500Subject._next @ Rx.js:9999Subject.next @ Rx.js:9963EventEmitter.emit @ angular2.dev.js:14366(anonymous function) @ angular2.dev.js:5612run @ angular2-polyfills.js:139NgZone._notifyOnTurnDone @ angular2.dev.js:5611(anonymous function) @ angular2.dev.js:5726zoneBoundFn @ angular2-polyfills.js:112lib$es6$promise$asap$$flush @ angular2-polyfills.js:1306
angular2.dev.js:23514 ORIGINAL EXCEPTION: TypeError: Cannot read property 'validator' of undefinedBrowserDomAdapter.logError @ angular2.dev.js:23514ExceptionHandler.call @ angular2.dev.js:1154(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:142(anonymous function) @ angular2.dev.js:5719NgZone.run @ angular2.dev.js:5681(anonymous function) @ angular2.dev.js:14884schedulerFn @ angular2.dev.js:14385tryCatcher @ Rx.js:31Subscriber.next @ Rx.js:9500Subject._next @ Rx.js:9999Subject.next @ Rx.js:9963EventEmitter.emit @ angular2.dev.js:14366(anonymous function) @ angular2.dev.js:5612run @ angular2-polyfills.js:139NgZone._notifyOnTurnDone @ angular2.dev.js:5611(anonymous function) @ angular2.dev.js:5726zoneBoundFn @ angular2-polyfills.js:112lib$es6$promise$asap$$flush @ angular2-polyfills.js:1306
angular2.dev.js:23514 ORIGINAL STACKTRACE:BrowserDomAdapter.logError @ angular2.dev.js:23514ExceptionHandler.call @ angular2.dev.js:1157(anonymous function) @ angular2.dev.js:14801NgZone._notifyOnError @ angular2.dev.js:5796collection_1.StringMapWrapper.merge.onError @ angular2.dev.js:5700run @ angular2-polyfills.js:142(anonymous function) @ angular2.dev.js:5719NgZone.run @ angular2.dev.js:5681(anonymous function) @ angular2.dev.js:14884schedulerFn @ angular2.dev.js:14385tryCatcher @ Rx.js:31Subscriber.next @ Rx.js:9500Subject._next @ Rx.js:9999Subject.next @ Rx.js:9963EventEmitter.emit @ angular2.dev.js:14366(anonymous function) @ angular2.dev.js:5612run @ angular2-polyfills.js:139NgZone._notifyOnTurnDone @ angular2.dev.js:5611(anonymous function) @ angular2.dev.js:5726zoneBoundFn @ angular2-polyfills.js:112lib$es6$promise$asap$$flush @ angular2-polyfills.js:1306
angular2.dev.js:23514 TypeError: Cannot read property 'validator' of undefined
    at NgFormModel.ngOnChanges (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:17831:73)
    at AbstractChangeDetector.ChangeDetector_NoteComponent_0.detectChangesInRecordsInternal (eval at <anonymous> (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:10897:14), <anonymous>:46:59)
    at AbstractChangeDetector.detectChangesInRecords (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8824:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8807:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8811:12)
    at AbstractChangeDetector._detectChangesContentChildren (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8871:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8808:12)
    at AbstractChangeDetector._detectChangesInViewChildren (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8877:14)
    at AbstractChangeDetector.runDetectChanges (http://localhost:3000/assets/angular2/bundles/angular2.dev.js:8811:12)

我已将下面的相关代码粘贴到变量应该相互通信的注释中。

import { Component, View } from 'angular2/core'
import { ROUTER_DIRECTIVES } from "angular2/router";
import { CORE_DIRECTIVES } from "angular2/common"
import Rx from 'rxjs/Rx'
import {Response} from 'angular2/http'
import {NoteService} from "../../services/note/NoteService.ts";
import {ROUTER_PROVIDERS} from "angular2/router";
import {RouteParams} from "angular2/router";
import {MarkdownRenderer} from "../markdownRenderer/markdownRenderer.ts";
import { Note } from "../../models/note/note.ts"
import {FORM_DIRECTIVES} from "angular2/common";
import {FormBuilder} from "angular2/common";
import {Validators} from "angular2/common";

@Component({
    selector: 'noteComponent',
    providers: [NoteService]
})

@View({
    directives: [MarkdownRenderer, FORM_DIRECTIVES]
    template: `
        <form [ngFormModel]="noteForm" (ngSubmit)="onSubmit(noteForm.value)">
        <div class="row animated">
            <div class="medium-10 columns medium-centered">
                <div *ngIf="note">
                    <div class="date-and-title animated fadeInDown">
                        <div class="medium-8 columns">
                            <h1 class="note-date">{{getDate(note.created_at)}}</h1>
                            <!--I'm trying to populate [ngFormControl]="noteForm.controls['title']"-->
                            <span>Title</span> <input type="text" class="note-title" [ngFormControl]="noteForm.controls['title']" *ngIf="note.title">
                        </div>
                        <div class="medium-4 columns end">
                           <input type="submit" class="button" value="Submit">
                        </div>

                    </div>
                    <div class="body">
                        <markdownRenderer [note]="note"></markdownRenderer>
                    </div>
                </div>
            </div>
        </div>
        </form>
    `
})

export class NoteComponent {
    note: Note

    constructor(noteService: NoteService, params: RouteParams, fb: FormBuilder){
        this.id = params.get('id')

        noteService.getNote(this.id)
            .subscribe((res: Response) =>{
                // this.note is defined here and works fine in my @View template decoration
                this.note = new Note(res.note.title, res.note.body, res.note.subject_id, res.note.created_at, res.note.updated_at)

                console.log(this.note) //note is logged as expected

                this.noteForm = fb.group({
                    title: [this.note.title, Validators.required] // TypeError: Cannot read property 'validator' of undefined in [noteForm in NoteComponent@1:14]
                })
            })
    }
}

1 个答案:

答案 0 :(得分:0)

问题是this.note尚未存在,因为您在subscribe回调中已经存在noteForm。因此,您需要在数据可用后设置constructor(noteService: NoteService, params: RouteParams, fb: FormBuilder){ this.id = params.get('id') noteService.getNote(this.id) .subscribe((res: Response) =>{ this.note = new Note(res.note.title, res.note.body, res.note.subject_id, res.note.created_at, res.note.updated_at) console.log(this.note) this.noteForm = fb.group({ title: [this.note.title, Validators.required] }) }

//super-component_controller.js
 ({
  fireEvent: function(component){
  var myEvent = $A.get("e.c:myEvent");
  myEvent.fire();
  console.log('event fired');
  }
})

<!-- nested-component -->
<aura:component>
   <aura:handler event="c:myEvent" action="{!c.gotEvent}" />
<aura:component>