Фон:
У меня есть сервис, где у меня есть открытая карта слоев. Компонент карты имеет собственный сервис.
При нажатии значка появляется всплывающее окно. В этом всплывающем окне находится кнопка, которая при нажатии извлекает некоторые данные из объекта, отображаемого во всплывающем окне, а затем перемещается к другому компоненту.
Я пытаюсь опубликовать / добавить эти данные в тему поведения, а затем подписаться на них в новом компоненте. Данные добавляются в тему поведения при нажатии на значок. У всплывающего компонента есть свой сервис.
В целевом компоненте я пытаюсь подписаться на тему поведения всплывающих сервисов в шаблоне с помощью асинхронной c трубы.
Проблема:
Наблюдаемое на субъекте поведения возвращает только начальное значение. Следующая функция объекта поведения, похоже, не добавляет к нему новые данные. Это всегда дает новое значение.
Когда используется тема воспроизведения, ничего не отображается. Следующая функция просто не имеет никакого эффекта.
Код:
Всплывающая служба
_analysisBehaviourSubject: BehaviorSubject<any> = new BehaviorSubject();
// other code
addElement(element: any) {
console.log('adding new element to behaviour subject', element);
this._analysisBehaviourSubject.next(element);
}
getElement$(): Observable<any> {
return this._analysisBehaviourSubject.asObservable();
}
Служба карт
getAnalysisBehaviourSubject(): Observable<any> {
return this.clusPopupService.getElement$();
}
Служба назначения
getAnalysisBehaviourSubject(): Observable<any> {
return this.mapService.getAnalysisBehaviourSubject();
}
Тогда в компоненте назначения есть просто асинхронный c канал.
То, что я уже пробовал:
импорт субъекта поведения непосредственно из всплывающего сервиса без его перемещения по структуре моего проекта.
с использованием субъекта поведения вместо субъекта воспроизведения, как показано в примере кода.
Добавление всех трех сервисов в массив провайдеров в app.module.ts. Субъект поведения по-прежнему излучает исходное значение, а субъект воспроизведения - вообще ничего.
Обновление: Всплывающая служба
import { DataPreparationService } from './data-preparation.service';
import { GeneralService } from '../../general.service';
import { Injectable } from '@angular/core';
import OlMap from 'ol/Map';
import OlView from 'ol/View';
import { fromLonLat } from 'ol/proj';
import Overlay from 'ol/Overlay';
import Point from 'ol/geom/Point.js';
import { SourceDataObject } from '../../Models/sourceDataObj';
import { Select } from 'ol/interaction';
import { CookieService } from 'ngx-cookie-service';
import { StoreService } from 'src/app/store.service';
@Injectable({
providedIn: 'root'
})
export class ClusterPopupService {
// analysis variables
deltaEX = 1;
deltaEy = 3;
overlayCoords: object = {};
sourceDataObj: SourceDataObject = { element: '', coordinates: null };
detectedPoints: Point[] = [];
// pop up variables
foundIcon: SourceDataObject;
newPoint: Point;
generalSelect: Select;
num = 0;
// analysis page Behaviour Subjects
constructor(
private genService: GeneralService,
private dataPrepService: DataPreparationService,
private cookies: CookieService,
private store: StoreService
) {}
// behaviour subject m1ethods
//cluster methods
filterPoints(newPoint: Point) {
const newPointCoords: number[] = newPoint.getCoordinates();
if (this.detectedPoints.length >= 1) {
for (let i = 0; i <= this.detectedPoints.length - 1; i++) {
const savedPointCoords = this.detectedPoints[i].getCoordinates();
if (
savedPointCoords[0] === newPointCoords[0] &&
savedPointCoords[1] === newPointCoords[1]
) {
break;
} else if (i === this.detectedPoints.length - 1) {
this.detectedPoints.push(newPoint);
}
}
} else {
this.detectedPoints.push(newPoint);
}
}
async clearFeatureCache() {
this.foundIcon = undefined;
this.generalSelect.getFeatures().clear();
this.detectedPoints = null;
}
pushToCookies(currView: OlView) {
this.cookies.deleteAll();
const currCoordinates: number[] = currView.getCenter();
const longitudeString: string = currCoordinates[0].toString();
const latitudeString: string = currCoordinates[1].toString();
const zoomLevelString: string = currView.getZoom().toString();
this.cookies.set('longitude', longitudeString, 1 / 48);
this.cookies.set('latitude', latitudeString, 1 / 48);
this.cookies.set('zoom', zoomLevelString, 1 / 48);
console.log(
this.cookies.get('longitude'),
this.cookies.get('latitude'),
this.cookies.get('zoom')
);
}
async preparePopup(
fishCoords: SourceDataObject[],
munitCoords: SourceDataObject[],
wrackCoords: SourceDataObject[],
sedimentCoords: SourceDataObject[],
generalSelect: Select,
view: OlView,
globalMap: OlMap,
localDoc?: Document
) {
const extent: number[] = view.calculateExtent(globalMap.getSize());
const container = localDoc.getElementById('popup');
const content = localDoc.getElementById('popup-content');
const closer = localDoc.getElementById('popup-closer');
const analyseButton = localDoc.getElementById('analyseButton');
const popUpOverlay: Overlay = new Overlay({
element: container,
autoPan: true
});
this.generalSelect = generalSelect;
closer.onclick = () => {
popUpOverlay.setPosition(undefined);
this.foundIcon = undefined;
generalSelect.getFeatures().clear();
this.detectedPoints = null;
this.newPoint = null;
closer.blur();
return false;
};
globalMap.addOverlay(popUpOverlay);
generalSelect.on('select', event => {
this.newPoint = event.selected[0].getGeometry() as Point;
this.foundIcon = this.dataPrepService.binSearch(
wrackCoords,
this.newPoint.getCoordinates(),
'wrack Array'
);
if (this.foundIcon === undefined) {
this.foundIcon = this.dataPrepService.binSearch(
sedimentCoords,
this.newPoint.getCoordinates(),
'sediment array'
);
}
if (this.foundIcon === undefined) {
this.foundIcon = this.dataPrepService.binSearch(
fishCoords,
this.newPoint.getCoordinates(),
'fish array'
);
}
if (this.foundIcon === undefined) {
this.foundIcon = this.dataPrepService.binSearch(
munitCoords,
this.newPoint.getCoordinates(),
'munition array'
);
}
if (this.foundIcon !== undefined) {
this.sourceDataObj = this.foundIcon;
popUpOverlay.setPosition(fromLonLat(this.foundIcon.coordinates));
} else {
if (this.sourceDataObj === null) {
this.sourceDataObj = { element: '', coordinates: null };
this.sourceDataObj.element = 'not found';
console.log(this.genService.backEndUri);
}
this.sourceDataObj.element = 'not found';
popUpOverlay.setPosition(this.newPoint.getCoordinates());
}
console.log('the icon found is:', this.foundIcon);
switch (this.sourceDataObj.element) {
case 'sediment':
content.innerHTML =
'<p>You clicked on a <code>' +
this.sourceDataObj.element +
'</code> with coordinates <code>' +
this.sourceDataObj.coordinates +
'</code>, and ID <code>' +
this.sourceDataObj.sampleId +
'</code>. Analyse this element?</p><p><button onclick="window.location.href=\'' +
this.genService.localUri +
'/analyseSediment' +
'\'"' +
'id="analyseButton">Analyse</button></p>';
this.sourceDataObj = null;
this.pushToCookies(view);
break;
case 'fish':
this.store.addElement(this.sourceDataObj.miscData);
content.innerHTML =
'<p>You clicked on a <code>' +
this.sourceDataObj.element +
'</code> with coordinates <code>' +
this.sourceDataObj.coordinates +
'</code>, cruise ID <code>' +
this.sourceDataObj.miscData.cruiseId +
'</code> and target ID <code>' +
this.sourceDataObj.miscData.sampleId +
'</code>. Analyse this element?</p><p><button onclick="window.location.href=\'' +
this.genService.localUri +
'/analyseFish' +
'\'"' +
' id="analyseButton">Analyse</button></p>';
this.sourceDataObj = null;
this.pushToCookies(view);
break;
case 'Munition':
content.innerHTML =
'<p>You clicked on a <code>' +
this.sourceDataObj.element +
'</code> with coordinates <code>' +
this.sourceDataObj.coordinates +
'</code>, cruise ID <code>' +
this.sourceDataObj.miscData.cruiseId +
'</code> and target ID <code>' +
this.sourceDataObj.miscData.targetId +
'</code>. Analyse this element?</p><p><button onclick="window.location.href=\'' +
this.genService.localUri +
'/analyseMunition' +
'\'"' +
'id="analyseButton">Analyse</button></p>';
this.sourceDataObj = null;
this.pushToCookies(view);
break;
case 'wrack':
content.innerHTML =
'<p>You clicked on a <code>' +
this.sourceDataObj.element +
'</code> with coordinates <code>' +
this.sourceDataObj.coordinates +
'</code>, and target ID <code>' +
this.sourceDataObj.miscData.targetId +
'</code>. Analyse this element?</p><p><button onclick="window.location.href=\'' +
this.genService.localUri +
'/analyseWrack' +
'\'"' +
' id="analyseButton">Analyse</button></p>';
this.sourceDataObj = null;
this.pushToCookies(view);
break;
case 'not found':
content.innerHTML =
'<p>You selected more than one Icon. Please Zoom in and select only one for analysis</p>';
break;
default:
content.innerHTML =
'<p>The map feature wasn"t quite selected. Please close the pop up and retry</p>';
break;
}
});
}
}
Служба хранилища
import { Injectable } from '@angular/core';
import { BehaviorSubject, ReplaySubject } from 'rxjs';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class StoreService {
_analysisBehaviourSubject: BehaviorSubject<any> = new BehaviorSubject();
analysis$: Observable<any> = this._analysisBehaviourSubject.asObservable();
constructor() {
console.log('I AM THE STORE');
}
addElement(element: any) {
console.log('adding new element to behaviour subject', element);
this._analysisBehaviourSubject.next(element);
}
getElement$(): Observable<any> {
return this.analysis$;
}
}