在我的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中添加一些配置时,我们可能会得到这样的消息:Property没有初始化式,并且在构造函数中没有明确地赋值。json文件,以便在严格模式下编译Angular项目:

"compilerOptions": {
  "strict": true,
  "noImplicitAny": true,
  "noImplicitThis": true,
  "alwaysStrict": true,
  "strictNullChecks": true,
  "strictFunctionTypes": true,
  "strictPropertyInitialization": true,

实际上,在使用成员变量之前,编译器会报错成员变量没有定义。

对于一个在编译时没有定义的成员变量的例子,一个成员变量有一个@Input指令:

@Input() userId: string;

我们可以通过声明变量可以是可选的来关闭编译器:

@Input() userId?: string;

但是,我们将不得不处理变量未定义的情况,并使用一些这样的语句使源代码混乱:

if (this.userId) {
} else {
}

相反,知道这个成员变量的值将及时定义,也就是说,它将在使用之前定义,我们可以告诉编译器不要担心它没有被定义。

告诉编译器这一点的方法是添加!明确赋值断言运算符,如:

@Input() userId!: string;

现在,编译器知道这个变量虽然没有在编译时定义,但应该在运行时以及在使用它之前及时定义。

现在由应用程序来确保在使用该变量之前已经定义了该变量。

作为一种额外的保护,我们可以在使用变量之前断言变量正在被定义。

我们可以断言变量已经定义,也就是说,所需的输入绑定实际上是由调用上下文提供的:

private assertInputsProvided(): void {
  if (!this.userId) {
    throw (new Error("The required input [userId] was not provided"));
  }
}

public ngOnInit(): void {
  // Ensure the input bindings are actually provided at run-time
  this.assertInputsProvided();
}

知道了变量的定义,现在可以使用变量:

ngOnChanges() {
  this.userService.get(this.userId)
    .subscribe(user => {
      this.update(user.confirmedEmail);
    });
}

注意,ngOnInit方法是在输入绑定尝试之后调用的,即使没有向绑定提供实际的输入。

而ngOnChanges方法在尝试输入绑定之后才会被调用,并且仅当有实际输入提供给绑定时才会调用。

其他回答

在我的Angular项目中添加Node时得到这个错误

TSError: ?无法编译TypeScript: (路径)/ base.api。ts:19:13 -错误TS2564:属性'apiRoot Path'没有初始化式,在构造函数中没有明确赋值。 private apiRootPath:字符串;

解决方案-

在tsconfig.json的compilerOptions中增加了"strictPropertyInitialization": false。

我的包。json -

"dependencies": {
    ...
    "@angular/common": "~10.1.3",
    "@types/express": "^4.17.9",
    "express": "^4.17.1",
    ...
}

参考URL - https://www.ryadel.com/en/ts2564-ts-property-has-no-initializer-typescript-error-fix-visual-studio-2017-vs2017/

我认为你使用的是最新版本的TypeScript。请参阅链接中的“严格类初始化”部分。

有两种方法可以解决这个问题:

A.如果你正在使用VSCode,你需要改变编辑器使用的TS版本。

B.在声明数组时初始化它

makes: any[] = [];

或者在构造函数内部:

constructor(private makeService: MakeService) { 
   // Initialization inside the constructor
   this.makes = [];
}

在我的情况下,它与不同的声明根据新的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/

在tsconfig.json中添加这两行

"noImplicitReturns": true,
"strictPropertyInitialization": false,

并确保strict设置为true

这个已经在Angular Github的https://github.com/angular/angular/issues/24571上讨论过了

我认为这是每个人都会转向的方向

引用自https://github.com/angular/angular/issues/24571#issuecomment-404606595

For angular components, use the following rules in deciding between:
a) adding initializer
b) make the field optional
c) leave the '!'

If the field is annotated with @input - Make the field optional b) or add an initializer a).
If the input is required for the component user - add an assertion in ngOnInit and apply c.
If the field is annotated @ViewChild, @ContentChild - Make the field optional b).
If the field is annotated with @ViewChildren or @ContentChildren - Add back '!' - c).
Fields that have an initializer, but it lives in ngOnInit. - Move the initializer to the constructor.
Fields that have an initializer, but it lives in ngOnInit and cannot be moved because it depends on other @input fields - Add back '!' - c).