Heim >Web-Frontend >js-Tutorial >Angular-Entwicklungsproblemdatensatz: Komponente kann das @Input-Eingabeattribut nicht abrufen

Angular-Entwicklungsproblemdatensatz: Komponente kann das @Input-Eingabeattribut nicht abrufen

青灯夜游
青灯夜游nach vorne
2022-12-09 20:17:142738Durchsuche

Als ich kürzlich eine Funktion bei der Arbeit implementiert habe, bin ich auf ein kleines Problem gestoßen: AngularDie Komponente kann das @Input-Eingabeattribut nicht abrufen. Obwohl ich mit diesen Problemen relativ vertraut bin, ist ein Prozess erforderlich, um das Problem zu finden Fassen Sie dieses Problem zusammen und notieren Sie es.

Angular-Entwicklungsproblemdatensatz: Komponente kann das @Input-Eingabeattribut nicht abrufen

【Verwandte Tutorial-Empfehlung: „angular Tutorial“】

Ich muss ein Eingabeattribut @Input auf eine Component setzen, okay, starten Sie einfach den Code, es ist nicht schwierig.

Der ursprüngliche Code sieht so aus:

@Component({
	selector: 'my-menu',
	templateUrl: './main-menu.widget.html'
})
export class MyMenuWidget {
  data: any[];
  
  ...

    constructor(...) {
       this._changesSubscription = this._service.changes.pipe(
            map((data: any[]) => {
                    ...
                    return data;
            })
        ).subscribe((data: any[]) => {
            this.data = data;
        });
    }

  ...
}

Fügen Sie ein Eingabeattribut hinzu:

@Component({
	selector: 'my-menu',
	templateUrl: './main-menu.widget.html'
})
export class MyMenuWidget {
  @Input() isMainMenu: boolean = false;

  data: any[];
  
  ...

    constructor(...) {
        this._changesSubscription = this._service.changes.pipe(
                map((data: any[]) => {
                        ...
                        return data;
                })
        ).subscribe((data: any[]) => {
            if (this.isMainMenu) {
               this.data = data.filter((d: any) => d.ID === 233);
            }
            else {
              this.data = data;
            }
        });
    }

  ...
}

Verwenden Sie es:

<my-menu [isMainMenu]="mainMenu"></my-menu>

Dann habe ich festgestellt, dass das Eingabeattribut isMainMenu in MyMenuWidget den Wert immer nicht erhalten kann. Wo ist die Schreibweise? Haben Sie eine Frage? Ich habe es überprüft und festgestellt, dass es überhaupt kein Problem gab, aber ich konnte den Wert einfach nicht ermitteln.

Schau mal genauer hin, ahhhh? ? ? , das Abonnement eines Observable wird tatsächlich im Konstruktor geschrieben! ! ! Obwohl das Schreiben auf diese Weise in einigen Szenarien normal funktionieren kann und die Funktion des Codes nicht beeinträchtigt, ist diese Schreibweise sehr unregelmäßig und verursacht Probleme, genau wie der Code im obigen Beispiel. Daher wird es während der normalen Entwicklung nicht empfohlen, so zu schreiben. Wie schreibt man es also richtig?

Laden Sie den Code hoch.

@Component({
	selector: &#39;my-menu&#39;,
	templateUrl: &#39;./main-menu.widget.html&#39;
})
export class MyMenuWidget {
  @Input() isMainMenu: boolean = false;

  data: any[];
  
  ...
  
  constructor(...) {
     ...
  }
  
    ngOnInit() {
        this._changesSubscription = this._service.changes.pipe(
            map((data: any[]) => {
                ...
                return data;
            })
        ).subscribe((data: any[]) => {
            if (this.isMainMenu) {
                    this.data = data.filter((d: any) => d.ID === 233);
            }
            else {
                this.data = data;
            }
        });
    }

  ...
}

Dann stellt sich die Frage: Warum kann derselbe Code normal funktionieren, wenn er in ngOnInit platziert wird? Manche Leute werden sagen, dass wir es einfach in ngOnInit einfügen sollten, aber nicht im Konstruktor. Warum also nicht, muss noch geklärt werden.

Die Frage ist, was ist der Unterschied zwischen dem Angular-Konstruktor und der ngOnInit-Funktion?

Unterschied 1

Unterschied in der Sprache:

Betrachten wir zunächst ihre Unterschiede aus sprachlicher Sicht. ngOnInit ist nur eine Methode der Komponentenklasse. Ihre Struktur unterscheidet sich nicht von anderen Methoden der Klasse, sie hat lediglich einen bestimmten Namen.

export class MyMenuWidget implements OnInit { 
   ngOnInit() {}
}

Es ist in Ordnung, es umzusetzen oder nicht. Ich kann es immer noch so schreiben, überhaupt kein Problem. Zur Implementierung dieser Schnittstelle ist kein explizites Markup erforderlich.

export class MyMenuWidget {
   ngOnInit() {}
}

So schreibe ich ES6. Wie schreibe ich den obigen Code in ES5?

Der Konstruktor unterscheidet sich völlig davon. Er wird beim Erstellen einer Klasseninstanz aufgerufen.

export class MyMenuWidget {
   constructor(){}
  
   ngOnInit() {}
}

Unterschied 2

Unterschied im Komponenteninitialisierungsprozess:

Aus Sicht der Komponenteninitialisierung ist der Unterschied zwischen den beiden immer noch sehr groß. Der Startvorgang von Angular besteht aus zwei Hauptphasen:
1. Erstellen Sie den Komponentenbaum.

Wenn Angular den Komponentenbaum erstellt, muss der Konstruktor neu aufgerufen werden Erstellen Sie eine Instanz, indem Sie den Konstruktor der Komponentenklasse aufrufen. Alle Lebenszyklus-Hooks, einschließlich ngOnInit, werden dann im Rahmen der Änderungserkennungsphase aufgerufen.

Wenn Angular mit der Änderungserkennung beginnt, wurde der Komponentenbaum erstellt und die Konstruktoren aller Komponenten im Baum wurden aufgerufen. Darüber hinaus wird an dieser Stelle der Vorlagenknoten jeder Komponente zum DOM hinzugefügt. Hier haben Sie Zugriff auf alle Daten, die Sie zur Initialisierung der Komponente benötigen – DI-Provider, DOM usw. Der @Input-Kommunikationsmechanismus wird als Teil der Änderungserkennungsphase behandelt, daher ist @Input im Konstruktor nicht verfügbar.

export class MyMenuWidget {
   constructor(private _elementRef: ElementRef){
     ...
   }
  
   ngOnInit() {}
}

Unterschied drei

Funktionale Unterschiede:

Für Angular

Konstruktor wird es hauptsächlich zur Initialisierung und zum Einfügen von Abhängigkeiten verwendet. Der übliche Ansatz besteht darin, so wenig Logik wie möglich in den Konstruktor einzubauen. Manchmal hat dies keinen Einfluss auf die Funktionalität, auch wenn Sie viel Logik einbauen.

Für

ngOnInit erstellt Angular das DOM der Komponente, verwendet den Konstruktor, um alle erforderlichen Abhängigkeiten einzufügen, und ruft nach Abschluss der Initialisierung ngOnInit auf. Dies ist ein guter Ort, um die Komponenteninitialisierungslogik auszuführen.

Einfach ausgedrückt

, der Konstruktor der Konstruktor selbst hat nichts mit Angular zu tun, ngOnInitDiese Hook-Funktionen sind in Angular definiert.

Zusammenfassung

Jetzt ist klar, warum @Input den Wert im Konstruktor nicht erhalten kann. Zukünftig wird klar sein, welche Logik im Konstruktor und welche in ngOnInit platziert werden soll.

Weitere Kenntnisse zum Thema Programmierung finden Sie unter:

Programmierlehre! !

Das obige ist der detaillierte Inhalt vonAngular-Entwicklungsproblemdatensatz: Komponente kann das @Input-Eingabeattribut nicht abrufen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:juejin.cn. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen