mframejs
Version:
simple framework
159 lines (114 loc) • 3.81 kB
text/typescript
import { ClassArrayObserver } from './classArrayObserver';
import { Cache } from '../../utils/exported';
import { IBindingContext } from '../../interface/exported';
// helper class (its faster this way)
const emptyObject = class {
// nothing
};
/*
* creates a observer for array on class/object
* classRef.__observerArray[this.keyBlock]
*
*/
export class ClassArrayObserverCreator {
private static classRef: any;
private static keyParts: any;
private static keyNo: any;
private static keyBlock: any;
/**
* create
*
*/
public static create(_class: IBindingContext, observerKey: string, caller: any) {
this.classRef = _class && _class.$context;
this.keyParts = Cache.keyMaps.getCreate(observerKey);
this.keyNo = 0;
this.keyBlock = this.keyParts[this.keyNo];
ClassArrayObserverCreator.processKeys(caller);
ClassArrayObserverCreator.clear();
}
/**
* removes the observer
*
*/
public static remove(_class: IBindingContext, observerKey: string, caller: any) {
this.classRef = _class.$context;
this.keyParts = Cache.keyMaps.getCreate(observerKey);
this.keyNo = 0;
this.keyBlock = this.keyParts[this.keyNo];
ClassArrayObserverCreator.removeKeys(caller);
ClassArrayObserverCreator.clear();
}
/**
* clear class
*
*/
private static clear() {
this.classRef = null;
this.keyParts = null;
this.keyNo = null;
this.keyBlock = null;
}
/**
* sets next key
*
*/
private static nextKey() {
this.keyNo++;
this.keyBlock = this.keyParts[this.keyNo];
}
/**
* added oberserver properties to object/class
*
*/
private static processKeys(caller: any) {
// add "__obeserver" prop if it does not exist
if (!this.classRef.__observerArray) {
Object.defineProperty(this.classRef, '__observerArray', {
writable: true,
configurable: true,
value: new emptyObject()
});
}
// create observer
if (!this.classRef.__observerArray[this.keyBlock]) {
this.classRef.__observerArray[this.keyBlock] = new ClassArrayObserver(this.classRef, this.keyBlock);
this.classRef.__observerArray[this.keyBlock].subscribe(caller);
} else {
this.classRef.__observerArray[this.keyBlock].subscribe(caller);
this.classRef.__observerArray[this.keyBlock].observe();
}
// if not next
if (this.keyNo !== this.keyParts.length - 1 && this.keyParts.length > 1) {
if (this.classRef) {
this.classRef = this.classRef[this.keyBlock];
}
this.nextKey();
if (this.classRef) {
this.processKeys(caller);
}
}
}
/**
* removes the caller
*
*/
private static removeKeys(caller: any) {
// unsubescribe
if (this.classRef.__observerArray) {
if (this.classRef.__observerArray[this.keyBlock]) {
this.classRef.__observerArray[this.keyBlock].unsubscribe(caller);
}
}
// if not next
if (this.keyNo !== this.keyParts.length - 1 && this.keyParts.length > 1) {
if (this.classRef) {
this.classRef = this.classRef[this.keyBlock];
}
this.nextKey();
if (this.classRef) {
this.removeKeys(caller);
}
}
}
}