在我的Angular应用中,我有一个组件:

import { MakeService } from './../../services/make.service';
import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-vehicle-form',
  templateUrl: './vehicle-form.component.html',
  styleUrls: ['./vehicle-form.component.css']
})
export class VehicleFormComponent implements OnInit {
  makes: any[];
  vehicle = {};

  constructor(private makeService: MakeService) { }

  ngOnInit() {
    this.makeService.getMakes().subscribe(makes => { this.makes = makes
      console.log("MAKES", this.makes);
    });
  }

  onMakeChange(){
    console.log("VEHICLE", this.vehicle);
  }
}

但是在“制造”属性中我犯了一个错误。 我不知道该怎么办……


当前回答

直接进入tsconfig。Ts和add "strictPropertyInitialization": false,进入compilerOptions对象。

如果还没有解决,请重新打开代码编辑器。

例子:

"compilerOptions" : {
  "strictPropertyInitialization": false,
}

其他回答

一个更好的方法是在变量的末尾加上感叹号,因为你确定它不是undefined或null,例如你正在使用一个ElementRef,需要从模板加载,不能在构造函数中定义,做如下所示的事情

class Component {
 ViewChild('idname') variable! : ElementRef;
}

在我的情况下,它与不同的声明根据新的typescript严格的特性:

@ViewChild(MatSort, {static: true}) sort!: MatSort;

如果在tsonfig中禁用typescript新的严格特性。json和

"compilerOptions": {
  ///
  ,
  "strictPropertyInitialization":false
}

旧的Angular指南代码工作得很好

@ViewChild(MatSort) sort: MatSort;

这里有4种方法来解决这个问题 Arunkumar Gudelli (2022) https://www.angularjswiki.com/angular/property-has-no-initializer-and-is-not-definitely-assigned-in-the-constructor/

你可以在构造函数中这样声明属性:

export class Test {
constructor(myText:string) {
this.myText= myText;
} 

myText: string ;
}

改变

fieldname?: any[]; 

:

fieldname?: any; 

该错误是合法的,可以防止应用程序崩溃。你输入了一个数组,但它也可以是未定义的。

你有两个选项(而不是禁用typescript存在的原因…):

1. 在你的情况下,最好是输入make,尽可能未定义。

makes?: any[]
// or
makes: any[] | undefined

所以当你试图访问make时,编译器会告诉你它可能是未定义的。 否则,如果下面的// <——Not ok行在getMakes完成之前执行,或者getMakes失败,你的应用程序将崩溃,并抛出一个运行时错误。这绝对不是你想要的。

makes[0] // <-- Not ok
makes.map(...) // <-- Not ok

if (makes) makes[0] // <-- Ok
makes?.[0] // <-- Ok
(makes ?? []).map(...) // <-- Ok

2. 您可以假设它永远不会失败,并且在编写下面的代码初始化之前永远不会尝试访问它(有风险!)所以编译器不会关心它。

makes!: any[] 

更具体地说,

你的代码设计可以做得更好。定义一个局部可变变量通常不是一个好的实践。你应该在你的服务中管理数据存储:

首先是nullsafe, 其次,能够分解大量代码(包括输入,加载状态和错误) 最后避免多次无用的reftech。

下面的例子试图展示这一点,但我没有测试它,它可以改进:

type Make = any // Type it

class MakeService {

  private readonly source = new BehaviorSubject<Make[] | undefined>(undefined);
  loading = false;

  private readonly getMakes = (): Observable<Make[]> => {
    /* ... your current implementation */
  };

  readonly getMakes2 = () => {
    if (this.source.value) {
      return this.source.asObservable();
    }
    return new Observable(_ => _.next()).pipe(
      tap(_ => {
        this.loading = true;
      }),
      mergeMap(this.getMakes),
      mergeMap(data => {
        this.source.next(data);
        return data;
      }),
      tap(_ => {
        this.loading = false;
      }),
      catchError((err: any) => {
        this.loading = false;
        return throwError(err);
      }),
    );
  };
}

@Component({
  selector: 'app-vehicle-form',
  template: `
    <div *ngIf="makeService.loading">Loading...</div>
    <div *ngFor="let vehicule of vehicules | async">
      {{vehicle.name}}
    </div>
  `,
  styleUrls: ['./vehicle-form.component.css']
})
export class VehicleFormComponent implements OnInit {
  constructor(public makeService: MakeService) {}

  readonly makes = this.makeService.getMakes2().pipe(
    tap(makes => console.log('MAKES', makes))
  );

  readonly vehicules = this.makes.pipe(
    map(make => make/* some transformation */),
    tap(vehicule => console.log('VEHICLE', vehicule)),
  );

  ngOnInit() {
    this.makes.subscribe(makes => {
      console.log('MAKES', makes);
    });
  }
}