Angular 2 route resolve错误:Uncaught(在promise中):TypeError:无法将undefined或null转换为object

时间:2016-12-20 10:45:03

标签: angular angular2-routing

我正在重复使用表单来创建和编辑记录。要编辑记录,我会尝试预加载数据但是当我点击“编辑”链接时,网址会快速闪烁以进行编辑

例如:http://localhost:4200/patients/-KYDTIA-kjTQaHm8_5Yy/edit

然后闪回原始状态:http://localhost:4200/patients/-KYDTIA-kjTQaHm8_5Yy并在浏览器上打开一个空表单。

奇怪的是,当我手动输入URL并在末尾包含/edit时,页面会预先加载正确的数据(有一些延迟,比如2秒)。

我使用的是AngularCLI(角度2.2.1),后端是Firebase,浏览器是Chrome。

我无法弄清楚以下内容:

  1. 当我在路由器配置中有一个解决方案以防止在预加载数据之前打开网址时,为什么会显示空表单。
  2. 为什么决心不预先加载数据。
  3. 为什么当我在URL的末尾手动输入/edit时,它按需要运行
  4. Image showing empty edit form loaded with error details in the console

    router.config.ts

    import { Route } from '@angular/router';
    import { PatientComponent } from './patient/patient.component';
    import { PatientDetailsComponent } from './patient-details/patient-details.component';
    import { NewPatientComponent } from './new-patient/new-patient.component';
    import { EditPatientComponent } from './edit-patient/edit-patient.component';
    import { LoginComponent } from './login/login.component';
    import { PatientResolver } from './shared/patient/patient.resolver';
    import { AuthGuard } from './shared/security/auth.guard';
    
    export const routerConfig: Route[] = [
    {
        path: 'patients',
        children:[
            {
                path: '',
                component: PatientComponent,
                canActivate: [AuthGuard]
            },
            {
                path: 'new',
                component: NewPatientComponent,
                canActivate: [AuthGuard]
            }
        ] 
    },
    {
        path: 'patients/:id',
        children: [
            {
                path: '',
                component: PatientDetailsComponent,
                canActivate: [AuthGuard]
            },
            {
                path: 'edit',
                component: EditPatientComponent,
                canActivate: [AuthGuard],
                resolve: {
                    patient: PatientResolver
                }
            }
        ]
    },
    {
        path: 'login',
        component: LoginComponent
    },
    {
        path: '',
        redirectTo: '/patients',
        pathMatch: 'full'
    },
    {
        path: '**',
        redirectTo: '/patients'
    }
    ];
    

    patient.resolver.ts

    import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
    import { Observable } from 'rxjs/Rx';
    import { Injectable } from '@angular/core';
    import { Patient } from './patient';
    import { PatientsService } from './patients.service';
    
    @Injectable()
    export class PatientResolver implements Resolve<Patient> {
    
    constructor(private _patientsService: PatientsService){}
    
    resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):Observable<Patient> {
        return this._patientsService
            .findPatientByUrl(route.params['id'])
            .first();
    }
    }
    

    修改-patient.component.ts

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Router } from '@angular/router';
    import { Location } from '@angular/common';
    import { PatientsService } from '../shared/patient/patients.service';
    import { Patient } from '../shared/patient/patient';
    
    @Component({
    selector: 'app-edit-patient',
    templateUrl: './edit-patient.component.html',
    styleUrls: ['./edit-patient.component.css']
    })
    export class EditPatientComponent implements OnInit {
    
    patient: Patient;
    msgs: any[];
    
    constructor(private _route: ActivatedRoute, 
              private _location: Location,
              private _patientsService: PatientsService,
              private _router: Router) 
    {
      _route.data.subscribe(data => this.patient = data['patient']);
    }
    
    ngOnInit() {}
    
    save(editedForm) {
    this._patientsService.savePatient(this.patient.$key, editedForm)
        .subscribe(
          () => {
            this.show();
          },
          err => this.showErr(err)
        );
     }
    
    show() {
     this.msgs = [];
     this.msgs.push({severity:'success', summary:'Confirmed', detail:'Record   successfully saved'});
    }
    
    showErr(err){
     this.msgs = [];
     this.msgs.push({severity:'error', summary:'Error Message', detail:`${err}`});
    }
    
    goBack() {
     this._router.navigate(['/patients']);
    }
    }
    

    链接以编辑patient.details.component.html

    <button class="btn btn-lblack" routerLink="edit">Edit</button>
    

    患者form.component.ts

    import { Component, OnInit, Input, OnChanges, SimpleChanges } from '@angular/core';
    import { FormBuilder, FormGroup, FormControl, Validators } from '@angular/forms';
    
    import { Patient } from '../shared/patient/patient';
    
    @Component({
      selector: 'patient-form',
      templateUrl: './patient-form.component.html',
      styleUrls: ['./patient-form.component.css']
    })
    export class PatientFormComponent implements OnInit, OnChanges {
    
      patientForm: FormGroup;
    
      @Input()
      patientValue: any;
    
      constructor(private _fb:FormBuilder) { 
        this.patientForm = this._fb.group({
          registrationNo: ['', Validators.required],
          patientName: ['', Validators.required],
          birth_year: ['', Validators.required],
          idNo: ['', Validators.required],
          gender: ['', Validators.required],
          telNo: ['', Validators.required],
          email: ['', Validators.required],
          dateCreated: [new Date()],
          dateUpdated: [new Date()]
        });
      }
    
      ngOnChanges(changes: SimpleChanges) {
        if(changes['patientValue']) {
          this.patientForm.patchValue(changes['patientValue'].currentValue);
        }
      }
    
      ngOnInit() { }
    
      isErrorVisible(field:string, error:string) {
    
        return this.patientForm.controls[field].dirty
          &&this.patientForm.controls[field].errors
          &&this.patientForm.controls[field].errors[error];
      }
    
      reset() {
        this.patientForm.reset();
      }
    
      get valid() {
        return this.patientForm.valid;
      }
    
      get value() {
        return this.patientForm.value;
      }
    
    }
    

    patient-form.component.html - 缩短

    <form [formGroup]="patientForm" autocomplete="off" novalidate>
    
        <legend>Patient Details</legend>
        <div class="row">
          <div class="col-md-6">
            <div class="form-group">
              <label for="formGroupRegNo">Registration No</label>
              <input type="text" class="form-control has-error" formControlName="registrationNo">
            </div>
          </div>
        </div>
        <div class="row">
          <div class="col-md-6">
            <div class="form-group">
              <label for="formGroupName">Full Name</label>
              <input type="text" class="form-control has-error" formControlName="patientName">
              <div class="field-error-message" *ngIf="isErrorVisible('patientName', 'required')">
                This field is mandatory
              </div>
            </div>
          </div>
          <div class="col-md-6">...</div>
        <div class="row">...</div>
    
    </form>
    

    修改-patient.component.html

    <div class="row">
      <div class="col-md-2"></div>
      <div class="col-md-8">
        <div class="card">
          <div class="card-header clearfix">
            <button class="btn btn-lblack float-xs-left" (click)="goBack()">
              <i class="fa fa-chevron-left" aria-hidden="true">
                </i> Back &amp; Cancel Changes
            </button>
            <button class="btn btn-lblack float-xs-right" (click)="save(patientForm.value)" >
              Save Changes
            </button>
          </div>
          <div class="card-block clearfix">
            <patient-form [patientValue]="patient" #patientForm></patient-form>
          </div>
        </div>
      </div>
    </div>
    

0 个答案:

没有答案