Angular:: 错误 TS2532:对象可能是 'undefined'

Angular:: error TS2532: Object is possibly 'undefined'

我在做 angular Tour-hero 项目(将 Hero 替换为 'User')。当我将 Hero(User) 和 Hero-detail(User-detail) 分开并尝试访问详细信息时,它没有显示,更新功能也不起作用。它显示此错误:

error TS2532: Object is possibly 'undefined'.

6 <input id="user-name" [(ngModel)]="user.name" placeholder="name">

我认为 user 对象给出了问题。但是,当我尝试完全按照本教程添加 MessageService 和所有内容时,它起作用了。但是当我删除所有这些时,它给出了这个错误。 在此先感谢您的帮助。

用户-detail.component.html:

<div>
  <h2>{{user.name | uppercase}} Details</h2>
  <div><span>id: </span>{{user.id}}</div>
  <div>
        <label for="user-name">User name: </label>
        <input id="user-name" [(ngModel)]="user.name" placeholder="name">
    </div>
    <button (click)="goBack()">Back</button>
    <button (click)="save()">Save</button>
</div>

用户-detail.component.ts:

import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';


@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
  user?: User

  constructor(
    private userService: UserService,
    private location: Location,
    private route: ActivatedRoute
  ) { }

  ngOnInit(): void {
    this.getUser();
  }

  getUser(): void {
    const id =
     parseInt(this.route.snapshot.paramMap.get('id')!, 1);
    this.userService.getUser(id)
      .subscribe(user => this.user = user);
  }

  goBack(): void {
    this.location.back();
  }

  save():void {
    if(this.user){
      this.userService.updateUser(this.user)
        .subscribe(() => this.goBack())
    }
  }

}

user.service.ts:

import { Injectable } from '@angular/core';
import { User } from 'src/app/model/user';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { catchError } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class UserService {
  
  private usersUrl = 'api/users/';

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json'})
  };

  getUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.usersUrl).pipe(
      catchError(this.handleError<User[]>('getUsers',[]))
    );
  }

  /** GET hero by id. Will 404 if id not found */
  getUser(id: number): Observable<User> {
    const url = `${this.usersUrl}/${id}`;
    return this.http.get<User>(url).pipe(
      catchError(this.handleError<User>(`getUser id=${id}`))
    );
  }

  updateUser(user: User): Observable<any> {
    return this.http.put(this.usersUrl, user, this.httpOptions)
    .pipe(
        catchError(this.handleError<User[]>('getUsers',[]))
    );
  }

  addUser(user: User): Observable<User>{
    return this.http.post<User>(this.usersUrl, user, this.httpOptions)
      .pipe(
        catchError(this.handleError<User>('addUser'))
      )
  }

  deleteUser(id: number): Observable<User>{
    const url = `${this.usersUrl}/${id}`;

    return this.http.delete<User>(url, this.httpOptions).pipe(
      catchError(this.handleError<User>('deleteUser'))
    )
  }

  constructor(private http: HttpClient) { }

  private handleError<T>(operation = 'operation', result?:T){
    return (error: any): Observable<T> => {
      console.error(error);
      return of(result as T);
    }
  }
}

您不需要将用户标记为可选

用户-detail.component.ts:

import { Component, OnInit } from '@angular/core';
import { User } from 'src/app/model/user';
import { UserService } from 'src/app/services/user/user.service';
import { Location } from '@angular/common';
import { ActivatedRoute } from '@angular/router';


@Component({
  selector: 'app-user-detail',
  templateUrl: './user-detail.component.html',
  styleUrls: ['./user-detail.component.scss']
})
export class UserDetailComponent implements OnInit {
  user: User

  constructor(
    private userService: UserService,
    private location: Location,
    private route: ActivatedRoute
  ) { }

  ngOnInit(): void {
    this.getUser();
  }

  getUser(): void {
    const id =
     parseInt(this.route.snapshot.paramMap.get('id')!, 1);
    this.userService.getUser(id)
      .subscribe(user => this.user = user);
  }

  goBack(): void {
    this.location.back();
  }

  save():void {
    if(this.user){
      this.userService.updateUser(this.user)
        .subscribe(() => this.goBack())
    }
  }

}

我认为此错误是由于 typescript 2.1 版或更高版本引起的,您的代码非常完美!没有任何问题,但变量未初始化的减速方式可能会导致此错误,

现在,如果您知道用户值或者您想使用任何默认值进行初始化,那么请在构造函数中初始化您的用户变量,如下所示

user: User;

constructor() {
  this.user = {
    id: 0,
    name: ''
  };
}

另一个解决方案是利用 'Definite Assignment Assertion' 告诉打字稿这个变量将在运行时有一个值,如下所示

component.ts

user!: User;

同时使用 component.html 文件进行更改,如下所示

<div>
  <h2>{{user?.name! | uppercase}} Details</h2>
  <div><span>id: </span>{{user?.id!}}</div>
  <div>
    <label for="user-name">User name: </label>
    <input id="user-name" [(ngModel)]="user?.name!" placeholder="name">
  </div>
  <button (click)="goBack()">Back</button>
  <button (click)="save()">Save</button>
</div>