我在服务中遇到了可观察的问题。以下代码说明了这一点:
@Injectable({
providedIn: 'root'
})
export class MyService {
public globalVariable: BehaviorSubject<string> = new BehaviorSubject('');
}
我有一个功能部件:
export class ComponentA implements OnInit {
constructor(public myService : MyService ) {
this.myService.globalVariable.next('newValue');
}
ngOnInit() {
this.myService.globalVariable.subscribe(_ => console.log('=> hello'));
}
}
应用模块:
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
ComponentAModule,
ComponentBModule,
AppRoutingModule
],
providers: [MyService],
bootstrap: [AppComponent]
})
export class AppModule {
}
最后是项目结构:
app-module.ts
app-routing.module.ts
-components
-- componentA
--- componentA.module.ts
--- componentA-routing.module.ts
--- componentA.component.ts
--- componentA.component.html
-- componentB
--- componentB.module.ts
--- componentB-routing.module.ts
--- componentB.component.ts
--- componentB.component.html
现在面临的问题是,当我导航到componentA
时,输出为:
=> hello
=> hello
直到现在,一切都正常,并且表现出预期。触发第一个订阅,然后由globalVariable
的构造函数在componentA
中进行更改。
但是,当我导航至componentB
并返回至componentA
时,输出为:
=> hello
=> hello
=> hello
每当我导航回componentA
时,它就会添加一个。好像它创建了MyService
的新实例?还是在离开时不破坏订阅?
信息:没有延迟加载。
答案 0 :(得分:1)
您需要在arrays
内$count = 0;
foreach($checkboxfiles as $checkboxfile) {
$src_file = $checkboxfile;
$fileName = basename($src_file);
$new_dest = $_POST['cbdestination'];
/* New path for this file */
$dest_file = $MainFolderName.'/'. $new_dest . '/' . $fileName;
if(file_exists($dest_file)){
$count++;
}
}
echo $count;
:
unsubscribe
答案 1 :(得分:1)
如果订阅不是由Angular自己处理的,则必须手动销毁它们。这基本上适用于您拥有的所有httpClient订阅。如果您例如使用| async
管道,Angular会取消订阅。
在组件的yourSubscription.unsubscribe()
中调用ngOnDestroy()
。
我通常要做的是创建一个BaseComponent
来替我取消订阅。通过扩展在所有组件中使用下面的类。将每个订阅呼叫都包装在super.addSubscription()
import { OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
/**
* This class handles the subscribing and unsubscribing of subscriptions to avoid memory leaks
* and can be inherited by members
*
* @export
*/
export abstract class BaseComponent implements OnDestroy {
private subscriptions: Subscription[] = new Array<Subscription>();
ngOnDestroy() {
this.removeSubscriptions();
}
/**
* Adds a subscriptions so it can be deleted in ngOnDestroy
*
* @param subscription The subscription that should be added
* @memberof BaseComponent
*/
protected addSubscription(subscription: Subscription) {
this.subscriptions.push(subscription);
}
/**
* Unsubscribes from any open subscriptions in the subscriptions array in ngOnDestroy
*
* @memberof AbstractBaseComponent
*/
private removeSubscriptions() {
for (let subscription of this.subscriptions) {
subscription.unsubscribe();
}
}
}
更新
假设您使用上面提供的基类,请对您的ngOnInit()
执行以下操作:
export class ComponentA extends BaseComponent implements OnInit {
constructor(public myService : MyService ) {
this.myService.globalVariable.next('newValue');
}
ngOnInit() {
super.addSubscription(
this.myService.globalVariable.subscribe(_ => console.log('=> hello'))
)
}
}
答案 2 :(得分:0)
如果要使用订阅管道而不是异步管道,则可以使用RxJs运算符takeWhile。请参见下面的代码...
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Observable } from 'rxjs';
import { takeWhile, map } from 'rxjs/operators';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit, OnDestroy {
name = 'Angular';
isActive: boolean;
// returned from service. Does not need to initialized here
thingToSubscribeTo:Observable<any> = new Observable<any>();
ngOnInit() {
this.isActive = true;
// you can replace with call to service then pipe it.
this.thingToSubscribeTo.pipe(
map(res => {
// handle subscription
}),
takeWhile(() => this.isActive)
);
}
ngOnDestroy() {
this.isActive = false;
}
}