change subscribe

This commit is contained in:
Sergey Krylov 2022-06-30 10:25:57 +05:00
parent a860f8d093
commit f0d90741dd
6 changed files with 67 additions and 11 deletions

View File

@ -2,6 +2,7 @@ import { Store } from '../../core/createStore';
import { $, Dom } from '../../core/dom';
import { Emitter } from '../../core/Emitter';
import { ExcelComponent } from '../../core/ExcelComponent';
import { StoreSubscriber } from '../../core/StoreSubscriber';
interface ExcelOptionsType {
components: any[],
@ -13,12 +14,14 @@ export class Excel {
components: any[];
emitter: Emitter;
store: Store;
subscriber: StoreSubscriber;
constructor(selector: string, options: ExcelOptionsType) {
this.$el = $(selector);
this.components = options.components;
this.emitter = new Emitter();
this.store = options.store;
this.subscriber = new StoreSubscriber(this.store);
console.log(`Created new Excel class in ${selector} with options: ${options}`);
}
@ -46,10 +49,13 @@ export class Excel {
render() {
this.$el.append(this.getRoot());
this.subscriber.subscribeComponents(this.components);
this.components.forEach(component => component.init());
}
destroy() {
this.subscriber.unsubscribeFromStore();
this.components.forEach(component => component.destroy());
}
}

View File

@ -10,6 +10,7 @@ export class Formula extends ExcelComponent {
super($root, {
listeners: ['input', 'keydown'],
name: 'Formula',
subscribe: ['currentText'],
...options,
});
}
@ -26,16 +27,13 @@ export class Formula extends ExcelComponent {
this.formulaInput = this.$root.find('#formula-input');
// this.$on('table:input', text => {
// this.formulaInput.text = text;
// });
this.$on('table:select-cell', text => {
this.formulaInput.text = text;
});
}
this.$subscribe(state => {
this.formulaInput.text = state.currentText;
});
storeChanged({ currentText = '' }) {
this.formulaInput.text = currentText;
}
onInput(event: Event) {

View File

@ -1,4 +1,4 @@
import { ActionType, StateType, SubscribeType } from '../redux/types';
import { ActionType, SubscribeType } from '../redux/types';
import { Store } from './createStore';
import { DomListener } from './DomListener';
import { Emitter } from './Emitter';
@ -6,6 +6,7 @@ import { Emitter } from './Emitter';
interface ExcelComponentClass {
toHTML: () => string;
prepare: () => void;
storeChanged?: (args: any) => void;
}
type OptionsType = {
@ -13,13 +14,15 @@ type OptionsType = {
name: string;
emitter?: Emitter;
store: Store;
subscribe: string[],
};
export class ExcelComponent extends DomListener implements ExcelComponentClass {
export abstract class ExcelComponent extends DomListener implements ExcelComponentClass {
name: string;
emitter: Emitter;
store: Store;
storeSub: SubscribeType;
subscribe: string[];
private unsubscribers: ((args?: any) => any)[];
constructor($root: any, options: OptionsType) {
@ -27,6 +30,8 @@ export class ExcelComponent extends DomListener implements ExcelComponentClass {
this.name = options?.name;
this.emitter = options?.emitter;
this.store = options?.store;
this.subscribe = options?.subscribe;
this.unsubscribers = [];
this.prepare();
}
@ -52,8 +57,12 @@ export class ExcelComponent extends DomListener implements ExcelComponentClass {
this.store.dispatch(action);
}
$subscribe(fn: (state?: StateType) => void) {
this.storeSub = this.store.subscribe(fn);
storeChanged(args?: any) {
console.log('CHANGE STORE: ', args);
}
isWatching(key: string) {
return this.subscribe?.includes(key);
}
init() {

View File

@ -0,0 +1,35 @@
import { StateType } from '../redux/types';
import { Store } from './createStore';
import { isEqual } from './utils';
export class StoreSubscriber {
sub: any;
prevState: StateType;
constructor(private store: Store) {
this.sub = null;
this.prevState = {};
}
subscribeComponents(components: any[]) {
this.prevState = this.store.getState();
this.sub = this.store.subscribe((state: StateType) => {
Object.keys(state).forEach(key => {
if (!isEqual(this.prevState[key], state[key])) {
components.forEach(component => {
if (component.isWatching(key)) {
const changes = { [key]: state[key] };
component.storeChanged(changes);
}
});
}
});
this.prevState = this.store.getState();
});
}
unsubscribeFromStore() {
this.sub.unsubscribe();
}
}

View File

@ -37,6 +37,6 @@ export class Store {
}
getState() {
return this.state;
return JSON.parse(JSON.stringify(this.state));
}
}

View File

@ -11,3 +11,11 @@ export function storage(key: string, data: any = null): any {
return true;
}
export function isEqual(a: any, b: any) {
if (typeof a === 'object' && typeof b === 'object') {
return JSON.stringify(a) === JSON.stringify(b);
}
return a === b;
}