In meiner Angular App habe ich eine Komponente:
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);
}
}
aber in der Eigenschaft "macht" habe ich einen Fehler. Ich weiß nicht, was ich damit anfangen soll ...
javascript
angular
typescript
Michael Kostiuchenko
quelle
quelle
Gehen Sie einfach zu tsconfig.json und setzen Sie
"strictPropertyInitialization": false
um den Kompilierungsfehler zu beseitigen.
Andernfalls müssen Sie alle Ihre Variablen initialisieren, was etwas ärgerlich ist
quelle
!
Postfix-Operator zum Variablennamen hinzuzufügen , diesen Fall einfach zu ignorieren oder die Variable im Konstruktor zu initialisieren.Dies liegt daran, dass TypeScript 2.7 eine strenge Klassenprüfung enthält, bei der alle Eigenschaften im Konstruktor initialisiert werden sollen. Eine Problemumgehung besteht darin, das
!
als Postfix zum Variablennamen hinzuzufügen :quelle
Möglicherweise wird die folgende Meldung angezeigt,
Property has no initializer and is not definitely assigned in the constructor
wenn dertsconfig.json
Datei eine Konfiguration hinzugefügt wird , damit ein Angular-Projekt im strengen Modus kompiliert wird:"compilerOptions": { "strict": true, "noImplicitAny": true, "noImplicitThis": true, "alwaysStrict": true, "strictNullChecks": true, "strictFunctionTypes": true, "strictPropertyInitialization": true,
In der Tat beschwert sich der Compiler dann darüber, dass eine Mitgliedsvariable vor ihrer Verwendung nicht definiert wurde.
Für ein Beispiel einer Mitgliedsvariablen, die zur Kompilierungszeit nicht definiert ist, eine Mitgliedsvariable mit einer
@Input
Direktive:Wir könnten den Compiler zum Schweigen bringen, indem wir angeben, dass die Variable optional sein kann:
Aber dann müssten wir uns mit dem Fall befassen, dass die Variable nicht definiert wird, und den Quellcode mit einigen solchen Anweisungen überladen:
if (this.userId) { } else { }
Wenn wir wissen, dass der Wert dieser Mitgliedsvariablen zeitlich definiert wird, dh vor der Verwendung definiert wird, können wir dem Compiler mitteilen, dass er sich keine Sorgen machen soll, dass er nicht definiert wird.
Die Möglichkeit, dies dem Compiler mitzuteilen, besteht darin, den
! definite assignment assertion
Operator wie folgt hinzuzufügen :Jetzt versteht der Compiler, dass diese Variable, obwohl sie zur Kompilierungszeit nicht definiert ist, zur Laufzeit und rechtzeitig definiert werden soll, bevor sie verwendet wird.
Es ist nun Sache der Anwendung, sicherzustellen, dass diese Variable definiert ist, bevor sie verwendet wird.
Als zusätzlichen Schutz können wir behaupten, dass die Variable definiert wird, bevor wir sie verwenden.
Wir können behaupten, dass die Variable definiert ist, dh die erforderliche Eingabebindung wurde tatsächlich vom aufrufenden Kontext bereitgestellt:
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(); }
Da die Variable definiert wurde, kann sie jetzt verwendet werden:
ngOnChanges() { this.userService.get(this.userId) .subscribe(user => { this.update(user.confirmedEmail); }); }
Beachten Sie, dass die
ngOnInit
Methode nach dem Versuch der Eingabebindungen aufgerufen wird, auch wenn für die Bindungen keine tatsächliche Eingabe bereitgestellt wurde.Während die
ngOnChanges
Methode nach dem Versuch der Eingabebindungen aufgerufen wird, und nur, wenn tatsächlich eine Eingabe für die Bindungen bereitgestellt wurde.quelle
Sie müssen entweder
--strictPropertyInitialization
das Sajeetharan-Dokument deaktivieren oder etwas Ähnliches tun, um die Initialisierungsanforderungen zu erfüllen:quelle
Sie können auch Folgendes tun, wenn Sie es wirklich nicht initialisieren möchten.
quelle
Ab TypeScript 2.7.2 müssen Sie eine Eigenschaft im Konstruktor initialisieren, wenn sie zum Zeitpunkt der Deklaration nicht zugewiesen wurde.
Wenn Sie aus Vue kommen, können Sie Folgendes versuchen:
Fügen Sie
"strictPropertyInitialization": true
Ihrer tsconfig.json hinzuWenn Sie mit dem Deaktivieren nicht zufrieden sind, können Sie dies auch versuchen
makes: any[] | undefined
. Dazu müssen Sie mit dem?.
Operator null check ( ) auf die Eigenschaften zugreifenthis.makes?.length
makes!: any[];
, dies teilt TS mit, dass der Wert zur Laufzeit zugewiesen wird.quelle
Wenn Sie ein Upgrade mit [email protected] durchführen, befolgt der Compiler strikt die Regeln für die Deklaration des Array-Typs im Komponentenklassenkonstruktor.
Um dieses Problem zu beheben, ändern Sie entweder den Code, der im Code deklariert ist, oder vermeiden Sie es, vom Compiler die Eigenschaft "strictPropertyInitialization": false in die Datei "tsconfig.json" einzufügen , und führen Sie npm start erneut aus.
Angular Web und Mobile Application Development finden Sie unter www.jtechweb.in
quelle
Können Sie nicht einfach eine bestimmte Zuweisungszusicherung verwenden? (Siehe https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-7.html#definite-assignment-assertions )
dh die Eigenschaft als
makes!: any[];
The! versichert Typoskript, dass es zur Laufzeit definitiv einen Wert geben wird.Es tut mir leid, dass ich dies nicht im Winkel versucht habe, aber es hat großartig für mich funktioniert, als ich genau das gleiche Problem in React hatte.
quelle