2

Ich habe eine Komponente mit Formcontrol und Abonnement auf ihrer Wertänderung:Wie zerstöre reaktive FormControl auf Komponente zerstören?

@Component(...) 
export class FooComponent implements OnInit, OnDestroy { 
    fooFormControl: FormControl; 

    ... 

    ngOnInit() { 
    this.fooFormControl.valueChanges.subscribe(
    () => {...}, 
    () => {}, 
    () => { 
     // never happens 
     }, 
    ); 
    } 

    ngOnDestroy() { 
    //happens 
    } 
} 

Aber als Komponente zerstört wurde, ist Formcontrol-Element nicht zerstört und onComplete Rückruf geschieht nie.

Was ist der richtige Weg, um FormControl-Element auf Komponente zu zerstören zerstören?

Antwort

0

Sie können Ihre Formularsteuerung nicht zerstören. Alles in der Komponente wird damit zerstört, aber die Ereignisse können in Ihrer App gespeichert werden. So können Sie die Ereignisse abbestellen.

@Component(...) 
export class FooComponent implements OnInit, OnDestroy { 
    fooFormControl: FormControl; 
    var subscriber; 

    ... 

    ngOnInit() { 
    this.subscriber = this.fooFormControl.valueChanges.subscribe(
    () => {...}, 
    () => {}, 
    () => { 
     // never happens 
     }, 
    ); 
    } 

    ngOnDestroy() { 
    this.subscriber.unsubscribe(); 
    } 
} 
2

FormControl Observablen nicht abgeschlossen werden soll, obwohl es möglich ist, dies manuell zu tun, wenn einige der Logik gibt es die Rückruf abzuschließen gehört.

Da valueChanges Ereignis-Emitter und erbt von RxJS Subject, kann es unsubscribed oder abgeschlossen sein:

ngOnDestroy() { 
    this.fooFormControl.valueChanges.complete(); 
    // and/or 
    this.fooFormControl.valueChanges.unsubscribe(); 
} 

Es ist möglich, dass EventEmitter wird kein Thema in Zukunft sein. Dies kann zu brechenden Änderungen führen, aber derzeit beruht es nur auf RxJS.

1

Hier sind zwei Ideen, die Ihnen helfen können. Ich bin mir nicht sicher, ob sie der "richtige Weg" sind, aber für mich hat es bisher sehr gut funktioniert. Außerdem kündige ich wie gewöhnlich in ngOnDestroy ab.

# 1 Force-Abschluss mit dem eigenen Thema über takeUntil

In Typoskript die valueChanges Eigenschaft Einführung ist vom Typ beobachtbar ist. Wenn Sie dies nicht umgehen und zum Thema gelangen möchten, können Sie mit dem Operator takeUntil einen eigenen Betreff eingeben. Auf diese Weise können Sie die Weiterleitung der Vervollständigung auf einen Wert oberhalb des beobachtbaren Werts Changes erzwingen. Es ist wichtig, den takeUntil-Operator nicht zu setzen, bevor eine Switchmap oder die zu beobachtbare Option fortgesetzt wird, und Ihr Abonnement wird nicht abgebrochen! Aus diesem Grund stelle ich es direkt vor den Abonnenten. Hier

ein Beispiel:

const stop = new Subject(); 

// simulate ngOnDestroy 
window.setTimeout(() => { 
    stop.next(); 
    stop.complete(); 
}, 3500); 

Observable 
    .interval(1000) 
    .takeUntil(stop) 
    .subscribe(
    () => { console.log('next'); }, 
    () => { console.log('error'); }, 
    () => { console.log('complete'); } 
); 

Hier ist ein funktionierendes Beispiel: https://rxviz.com/v/RoQNBnOM

# 2 fügen Sie die Formbuilder zu Ihrer Komponente Anbieterliste

Dies ist, was ich in der Regel tun. Eigentlich verkapsele ich normalerweise mein Formular in einem Dienst, der den FormBuilder verwendet, aber der Effekt ist derselbe. Wenn der Dienst auf dieser Ebene bereitgestellt wird, wird der Dienst bei jeder Erstellung der Komponente zerstört und neu erstellt. Ich fing an, dies zu tun, weil ich immer wieder seltsame Bugs hatte, die durch beobachtbare Streams verursacht wurden, die außerhalb von valueChanges erstellt wurden, die über die Lebensdauer der Komponente hinaus bestanden. Sie würden neu abonniert werden, wenn die Komponente neu erstellt wurde und solche Sachen. Hier

ein Beispiel:

@Component({ 
    selector: 'my-form', 
    templateUrl: './my-form.component.html', 
    styleUrls: ['./my-form.component.scss'], 
    changeDetection: ChangeDetectionStrategy.OnPush, 
    providers: [ FormBuilder ] // <-- THIS PART 
}) 
export class MyFormComponent implements OnInit, OnDestroy { 
} 

Beachten Sie, dass dies nicht wirklich Abschluss propagieren. Aber es gibt Ihnen jedes Mal ein neues Quellensubjekt.

Verwandte Themen