2

は、私はそれの価値変動に関するFormControlを持つコンポーネントおよびサブスクリプションを持っている:どのようにコンポーネントの破壊的なFormControlを破壊するか?

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

    ... 

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

    ngOnDestroy() { 
    //happens 
    } 
} 

しかし、部品が破壊されたときFormControl要素が破壊されていないと、onCompleteのコールバックは決して起こりません。

コンポーネントを破壊するFormControl要素を破壊する正しい方法は何ですか?

答えて

0

フォームコントロールを破棄することはできません。コンポーネント内のすべてが破棄されますが、イベントはアプリケーションに保持されます。だからあなたはそれをイベントから退会することができます。コールバックを完了するために属し、いくつかのロジックがある場合、手動でこれを行うことが可能であるが、

@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観測が完了することになっていません。 valueChangesので

イベントエミッタとRxJS Subjectから継承し、それは解除または完了させることができる。

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

EventEmitterが将来的に対象としないことが可能です。これは変更を破る可能性がありますが、現在のところ、RxJSのみに依存しています。

1

あなたに役立つ2つのアイデアがあります。彼らが「正しい方法」であるかどうかは分かりませんが、これまでのところ私にとってはかなりうまくいきました。この他にも、いつものようにngOnDestroyを退会しています。 takeUntilを経由して、独自の件名を導入することで

#1フォース完了

活字体でvalueChangesプロパティはタイプで観察可能です。それを回避してSubjectに到達したくない場合は、takeUntil演算子を使用して自分のSubjectを紹介することができます。これにより、観察可能なvalueChangesより上のレベルで補完の伝播を強制することができます。 switchmapの前にtakeUntilオペレータを置かないことが重要です。そうでないと、observableに切り替えられ、サブスクリプションはキャンセルされません。その理由から私はサブスクライブするオペレータの直前に置いた。これは私が通常何をすべきかは、あなたのコンポーネントのプロバイダリスト

にFormBuilderを追加https://rxviz.com/v/RoQNBnOM

#2:

ここ
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'); } 
); 

は実施例である:ここでは

は一例です。実際、私は通常FormBuilderを使用するサービスの中に自分のフォームをカプセル化しますが、その効果は同じです。このレベルでサービスを提供すると、コンポーネントが作成されるたびにサービスが破棄され再作成されます。私はコンポーネントの寿命を過ぎても持続するvalueChangesから作成された観測可能なストリームによって引き起こされた変なバグを抱えていたので、これをやり始めました。コンポーネントが再作成され、そのようなものになったときに再登録されます。これは実際に完了を伝播しないことを

@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 { 
} 

注:ここでは

は一例です。しかし、それはあなたに毎回新鮮なソースを与えます。

関連する問題