У меня есть два компонента angular, которые запускают код в фоновом режиме с помощью Observable.interval. Каждый компонент должен воспроизводить звук при возникновении данного события, но только компонент, который в настоящее время «видим», должен фактически воспроизводить звук. Компоненты становятся «видимыми» на основе текущего маршрута.
Что сейчас происходит, так это то, что оба компонента воспроизводят звук, и он звучит искаженно. Я думал, что я должен определять, является ли компонент «видимым», и не воспроизводить звук для этого компонента при таких обстоятельствах.
Есть ли способ определить, используется ли компонент, или есть другой способ выполнить это требование для воспроизведения звука?
Код, я обрезал нерелевантный код, чтобы сэкономить место
ViewUpdateService предоставляет наблюдаемую, на которую подписываются компоненты.
@Injectable()
export class ViewUpdateService {
constructor(@Inject(PLATFORM_ID) private platformId: Object) {
this.notifier = isPlatformBrowser(this.platformId)
? Observable.interval(250)
: Observable.empty();
}
notifier: Observable<any>;
}
ListComponent - это первый компонент, который должен издавать звук в данный момент времени.
@Component()
export class ListComponent implements OnInit {
private soundHandler(): void {
if (!this.triggerEventOccurred)
return;
if (this.shouldPlaySoundIfVisible)
this.kerching.play();
}
// ... removed to preserve space ...
constructor(private viewUpdateService: ViewUpdateService) {}
ngOnInit(): void {
this.dataService.getList()
.subscribe(l => this.handle(l));
this.viewUpdateService.notifier
.subscribe(t => this.soundHandler());
}
}
ДетальКомпонент - второй компонент, который должен воспроизводить звук в другой момент времени.
@Component()
export class DetailComponent implements OnInit {
private soundHandler(): void {
if (!this.triggerEventOccurred)
return;
if (this.shouldPlaySoundIfVisible)
this.kerching.play();
}
// ... removed to preserve space ...
constructor(private route: ActivatedRoute,
private viewUpdateService: ViewUpdateService) {}
ngOnInit(): void {
this.route.paramMap
.switchMap((params: ParamMap) => {
const id = params.get('id');
if (!id)
return Observable.empty();
return this.dataService.get();
})
.subscribe(s => this.handle(s));
this.viewUpdateService.notifier
.subscribe(t => this.soundHandler());
}
}
Компоненты становятся видимыми с помощью угловой трассировки.
export const DrawRoute: Route = {
path: 'draw',
children: [
{ path: ':id', component: DetailComponent, },
{ path: '', component: ListComponent, },
]
};
Вы вообще отменяете / отказываетесь от подписки на наблюдаемое?
Кроме того, включите в свой вопрос соответствующий код, в идеале в виде минимально воспроизводимого фрагмента.





Очень абстрактно, поскольку вы не предоставили слишком много деталей.
Выделите воспроизведение звука в отдельный компонент, извлеките Observable.interval в отдельный сервис.
Используйте компонент воспроизведения звука в component1 и component2 (видимость которых вы переключаете с помощью *nfIg) и используйте свой Observable.interval в компоненте воспроизведения звука.
Компонент воспроизведения звука может получить параметр @Input() contextType, сообщающий ему, какой родитель использует его, поскольку звуки корпуса должны быть разными для component1 и component2.
[ОБНОВЛЕНИЕ на основе добавленного вами контекста]
Поскольку воспроизведение звука, очевидно, является общим для обоих компонентов, я бы извлек его в отдельный soundPlayingComponent, использовал бы его в родительском, где используются ListComponent и DetailsComponent, и попросил бы эти два предоставить Output() playSound:EventEmitter<whateverParamsYouNeed> родителю на основе того, какой соответствующий звук будет воспроизводиться.
Извините, это было после 23:00, мозг уже засыпает ;-) Расскажу поподробнее.
Что вы определяете как «используется»? Создан ли и смонтирован ли компонент в DOM?