这里有两个想法可以帮助你。不确定它们是否是“正确的方法”,但到目前为止它对我来说效果很好。除此之外,我像往常一样取消订阅 ngOnDestroy。
#1 通过 takeUntil 引入你自己的主题来强制完成
在 TypeScript 中,valueChanges 属性属于 Observable 类型。如果您不想解决这个问题并进入主题,那么您可以使用 takeUntil 运算符来介绍您自己的主题。这将允许您强制在 valueChanges observable 之上的级别传播完成。重要的是不要将 takeUntil 运算符放在 switchmap 之前,否则切换到 observable 将继续并且您的订阅不会被取消!出于这个原因,我把它放在订阅运算符之前。
这是一个例子:
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'); }
);
这是一个工作示例:https ://rxviz.com/v/RoQNBnOM
#2 将 FormBuilder 添加到组件的提供者列表中
这是我通常做的。实际上,我通常将表单封装在使用 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 {
}
请注意,这实际上并不传播完成。但它确实每次都给你一个新的来源主题。