change subscribe
This commit is contained in:
parent
a860f8d093
commit
f0d90741dd
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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() {
|
||||
|
||||
35
src/core/StoreSubscriber.ts
Normal file
35
src/core/StoreSubscriber.ts
Normal 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();
|
||||
}
|
||||
}
|
||||
@ -37,6 +37,6 @@ export class Store {
|
||||
}
|
||||
|
||||
getState() {
|
||||
return this.state;
|
||||
return JSON.parse(JSON.stringify(this.state));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user