projects/angular-cesium/src/lib/angular-cesium/components/ac-array-desc/ac-array-desc.component.ts
This is component represents an array under ac-layer
.
The element must be a child of ac-layer element.
{string}
- get the tracked array and entityName (see the example).{Function}
- a function that gets the id for a given element in the array -should be defined for maximum performance.{boolean}
- show/hide array's entities.Usage :
*<ac-layer acFor="let track of tracks$" [show]="show" [context]="this" [store]="true">
* <ac-array-desc acFor="let arrayItem of track.array" [idGetter]="trackArrayIdGetter">
* <ac-array-desc acFor="let innerArrayItem of arrayItem.innerArray" [idGetter]="trackArrayIdGetter">
* <ac-point-desc props="{
* position: innerArrayItem.pos,
* pixelSize: 10,
* color: getTrackColor(track),
* outlineColor: Cesium.Color.BLUE,
* outlineWidth: 1
* }">
* </ac-point-desc>
* </ac-array-desc>
* </ac-array-desc>
*</ac-layer>
*
OnChanges
OnInit
AfterContentInit
OnDestroy
IDescription
changeDetection | ChangeDetectionStrategy.OnPush |
selector | ac-array-desc |
template |
|
Properties |
|
Methods |
Inputs |
constructor(layerService: LayerService, cd: ChangeDetectorRef)
|
|||||||||
Parameters :
|
acFor
|
Type : |
idGetter
|
Type : |
show
|
Default value : |
draw |
draw(context: any, id: string, contextEntity: any)
|
Returns :
void
|
Private generateCombinedId |
generateCombinedId(entityId: string, arrayItem: any, index: number)
|
Returns :
string
|
getAcForString |
getAcForString()
|
Returns :
string
|
ngAfterContentInit |
ngAfterContentInit()
|
Returns :
void
|
ngOnChanges | ||||||
ngOnChanges(changes: SimpleChanges)
|
||||||
Parameters :
Returns :
void
|
ngOnDestroy |
ngOnDestroy()
|
Returns :
void
|
ngOnInit |
ngOnInit()
|
Returns :
void
|
remove | ||||||
remove(id: string)
|
||||||
Parameters :
Returns :
void
|
removeAll |
removeAll()
|
Returns :
void
|
setLayerService | ||||||
setLayerService(layerService: LayerService)
|
||||||
Parameters :
Returns :
void
|
Private Readonly acForRgx |
acForRgx:
|
Default value : /^let\s+.+\s+of\s+.+$/
|
Private arrayDescs |
arrayDescs:
|
Type : any
|
Decorators :
@ContentChildren(AcArrayDescComponent, {descendants: undefined})
|
arrayObservable$ |
arrayObservable$:
|
Default value : new Subject<AcNotification>()
|
arrayPath |
arrayPath:
|
Type : string
|
Private basicDescs |
basicDescs:
|
Type : any
|
Decorators :
@ContentChildren(BasicDesc, {descendants: undefined})
|
Private entitiesMap |
entitiesMap:
|
Default value : new Map<string, string[]>()
|
entityName |
entityName:
|
Type : string
|
Private id |
id:
|
Type : number
|
Default value : 0
|
Private layer |
layer:
|
Type : AcLayerComponent
|
Decorators :
@ViewChild('layer', {static: undefined})
|
Public layerService |
layerService:
|
Type : LayerService
|
Private layerServiceSubscription |
layerServiceSubscription:
|
Type : Subscription
|
import {
AfterContentInit,
ChangeDetectionStrategy,
ChangeDetectorRef,
Component,
ContentChildren,
Input,
OnChanges,
OnDestroy,
OnInit,
SimpleChanges,
ViewChild
} from '@angular/core';
import { AcNotification } from '../../models/ac-notification';
import { Subject, Subscription } from 'rxjs';
import { IDescription } from '../../models/description';
import * as _get from 'lodash.get';
import { AcLayerComponent } from '../ac-layer/ac-layer.component';
import { LayerService } from '../../services/layer-service/layer-service.service';
import { BasicDesc } from '../../services/basic-desc/basic-desc.service';
/**
* This is component represents an array under `ac-layer`.
* The element must be a child of ac-layer element.
* + acFor `{string}` - get the tracked array and entityName (see the example).
* + idGetter `{Function}` - a function that gets the id for a given element in the array -should be defined for maximum performance.
* + show `{boolean}` - show/hide array's entities.
*
* __Usage :__
* ```
*<ac-layer acFor="let track of tracks$" [show]="show" [context]="this" [store]="true">
* <ac-array-desc acFor="let arrayItem of track.array" [idGetter]="trackArrayIdGetter">
* <ac-array-desc acFor="let innerArrayItem of arrayItem.innerArray" [idGetter]="trackArrayIdGetter">
* <ac-point-desc props="{
* position: innerArrayItem.pos,
* pixelSize: 10,
* color: getTrackColor(track),
* outlineColor: Cesium.Color.BLUE,
* outlineWidth: 1
* }">
* </ac-point-desc>
* </ac-array-desc>
* </ac-array-desc>
*</ac-layer>
* ```
*/
@Component({
selector: 'ac-array-desc',
template: `
<ac-layer #layer [acFor]="getAcForString()"
[context]="layerService.context"
[options]="layerService.options"
[show]="layerService.show && show"
[zIndex]="layerService.zIndex">
<ng-content #content></ng-content>
</ac-layer>
`,
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AcArrayDescComponent implements OnChanges, OnInit, AfterContentInit, OnDestroy, IDescription {
@Input() acFor: string;
@Input() idGetter: (item: any, index: number) => string;
@Input() show = true;
@ViewChild('layer', {static: true}) private layer: AcLayerComponent;
@ContentChildren(BasicDesc, {descendants: false}) private basicDescs: any;
@ContentChildren(AcArrayDescComponent, {descendants: false}) private arrayDescs: any;
private entitiesMap = new Map<string, string[]>();
private layerServiceSubscription: Subscription;
private id = 0;
private readonly acForRgx = /^let\s+.+\s+of\s+.+$/;
entityName: string;
arrayPath: string;
arrayObservable$ = new Subject<AcNotification>();
constructor(public layerService: LayerService, private cd: ChangeDetectorRef) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['acFor'].firstChange) {
const acForString = changes['acFor'].currentValue;
if (!this.acForRgx.test(acForString)) {
throw new Error(`ac-layer: Invalid [acFor] syntax. Expected: [acFor]="let item of observable" .Instead received: ${acForString}`);
}
const acForArr = changes['acFor'].currentValue.split(' ');
this.arrayPath = acForArr[3];
this.entityName = acForArr[1];
}
}
ngOnInit(): void {
if (this.layer) {
this.layer.getLayerService().cache = false;
}
this.layerServiceSubscription = this.layerService.layerUpdates().subscribe(() => {
this.cd.detectChanges();
});
}
ngAfterContentInit(): void {
this.layerService.context['arrayObservable$'] = this.arrayObservable$;
this.layerService.registerDescription(this);
this.basicDescs._results.forEach((component: BasicDesc) => {
component.setLayerService(this.layer.getLayerService());
});
this.arrayDescs._results.splice(0, 1);
this.arrayDescs._results.forEach((component: AcArrayDescComponent) => {
this.layerService.unregisterDescription(component);
this.layer.getLayerService().registerDescription(component);
component.layerService = this.layer.getLayerService();
component.setLayerService(this.layer.getLayerService());
});
}
ngOnDestroy(): void {
if (this.layerServiceSubscription) {
this.layerServiceSubscription.unsubscribe();
}
}
setLayerService(layerService: LayerService) {
this.layerService = layerService;
}
draw(context: any, id: string, contextEntity: any) {
const get = _get;
const entitiesArray: any[] = get(context, this.arrayPath);
if (!entitiesArray) {
return;
}
const previousEntitiesIdArray = this.entitiesMap.get(id);
const entitiesIdArray: any[] = [];
this.entitiesMap.set(id, entitiesIdArray);
entitiesArray.forEach((item, index) => {
this.layerService.context[this.entityName] = item;
const arrayItemId = this.generateCombinedId(id, item, index);
entitiesIdArray.push(arrayItemId);
this.layer.update(contextEntity, arrayItemId);
});
if (previousEntitiesIdArray) {
const entitiesToRemove = this.idGetter ?
previousEntitiesIdArray.filter((entityId) => entitiesIdArray.indexOf(entityId) < 0) :
previousEntitiesIdArray;
if (entitiesToRemove) {
entitiesToRemove.forEach((entityId) => this.layer.remove(entityId));
}
}
}
remove(id: string) {
const entitiesIdArray = this.entitiesMap.get(id);
if (entitiesIdArray) {
entitiesIdArray.forEach((entityId) => this.layer.remove(entityId));
}
this.entitiesMap.delete(id);
}
removeAll() {
this.layer.removeAll();
this.entitiesMap.clear();
}
getAcForString() {
return `let ${this.entityName + '___temp'} of arrayObservable$`;
}
private generateCombinedId(entityId: string, arrayItem: any, index: number): string {
let arrayItemId;
if (this.idGetter) {
arrayItemId = this.idGetter(arrayItem, index);
} else {
arrayItemId = (this.id++) % Number.MAX_SAFE_INTEGER;
}
return entityId + arrayItemId;
}
}