我在角度4中有一个应用程序,我用这种方式构建了几乎所有组件:
export class AreaProdottiComponent implements OnInit,OnDestroy {
subscription: ISubscription;
constructor(private someservice:Service){
this.subscription = someserviceObservable.subscribe(
res=>{
console.log('everything ok')
}
)
}
ngOnInit(){
this.someservice.fn()
}
ngOnDestroy(){
this.subscription.unsubscribe()
}
}
这些组件与几乎以这种方式构建的服务相互作用:
export class Service(){
someservicesubj=Subject<any>();
someserviceObservable=someservicesubj.asObservable();
fn(){
doCall.subscribe(
res=>{
this.someservicesubj.next();
}
)
}
doCall()Observable<any>{
//some http call is here
}
}
因此,当创建这样的组件时,他们会从服务中调用自动HTTP方法,并且一切似乎都有效,但是如果我导航应用程序并且第二次返回相同的组件则调用的数量一旦创建了组件加倍,就会调用fn方法2次。每次我销毁并重新创建组件时,此行为都会增加。
示例:
在控制台中打开组件我会读'一切正常',出去然后回来我会读'一切正常'3次,旧的加2其他。
我认为我在导航策略或服务构建中遗漏了一些东西,但我真的不知道解决方案。
我曾经尝试过@trichetriche建议,但它仍然没有用。我使用ISubscription而不是可能的问题?
@trichetriche是对的,但我有一个服务在另一个订阅者内部调用,所以我错过了这是第一个取消订阅的服务
答案 0 :(得分:1)
这是因为打开订阅时需要关闭订阅。你不要关闭它们。
我不会评论为HTTP调用创建主题的不成功。
export class AreaProdottiComponent implements OnInit, OnDestroy {
subscription: Subscription;
constructor(private someservice:Service){
this.subscription = someserviceObservable.subscribe(res => console.log('everything ok'));
}
ngOnInit(){
this.someservice.fn()
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
如果您想自动取消订阅订阅,可以使用装饰器。
export const randomString = () => Math.random().toString(36).slice(-8);
export function AutoUnsubscribe(blacklist = []) {
return function (constructor) {
const original = constructor.prototype.ngOnDestroy;
constructor.prototype.ngOnDestroy = function () {
// tslint:disable-next-line:forin
for (const prop in this) {
const property = this[prop];
if (!blacklist.includes(prop)) {
if (property && (typeof property.unsubscribe === 'function')) {
property.unsubscribe();
// console.log(prop + ' unsubscribed');
}
}
}
if (original && typeof original === 'function') { original.apply(this, arguments); }
};
};
}
现在您的组件看起来像这样
@AutoUnsubscribe()
export class AreaProdottiComponent implements OnInit, OnDestroy {
subscription: Subscription;
constructor(private someservice:Service){
this[randomString()] = someserviceObservable.subscribe(res => console.log('everything ok'));
}
ngOnInit(){
this.someservice.fn()
}
}
答案 1 :(得分:0)
原因是,您永远不会取消订阅您在组件构造函数中创建的订阅。每次组件实例化时,都会打开一个新订阅,因此每次导航到该组件时,日志都会增加一个。
如果要阻止此行为,则应保存订阅并使用ngOnDestroy
方法将其关闭:
export class AreaProdottiComponent implements OnInit, OnDestroy {
private subscription: Subscription;
constructor(private someservice:Service){
this.subscription = someserviceObservable.subscribe(
res=>{
console.log('everything ok')
}
)
}
ngOnInit(){
this.someservice.fn()
}
public ngOnDestroy(): void {
if (this.subscription) this.subscription.unsubscribe();
}
}