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 { $, Dom } from '../../core/dom';
|
||||||
import { Emitter } from '../../core/Emitter';
|
import { Emitter } from '../../core/Emitter';
|
||||||
import { ExcelComponent } from '../../core/ExcelComponent';
|
import { ExcelComponent } from '../../core/ExcelComponent';
|
||||||
|
import { StoreSubscriber } from '../../core/StoreSubscriber';
|
||||||
|
|
||||||
interface ExcelOptionsType {
|
interface ExcelOptionsType {
|
||||||
components: any[],
|
components: any[],
|
||||||
@ -13,12 +14,14 @@ export class Excel {
|
|||||||
components: any[];
|
components: any[];
|
||||||
emitter: Emitter;
|
emitter: Emitter;
|
||||||
store: Store;
|
store: Store;
|
||||||
|
subscriber: StoreSubscriber;
|
||||||
|
|
||||||
constructor(selector: string, options: ExcelOptionsType) {
|
constructor(selector: string, options: ExcelOptionsType) {
|
||||||
this.$el = $(selector);
|
this.$el = $(selector);
|
||||||
this.components = options.components;
|
this.components = options.components;
|
||||||
this.emitter = new Emitter();
|
this.emitter = new Emitter();
|
||||||
this.store = options.store;
|
this.store = options.store;
|
||||||
|
this.subscriber = new StoreSubscriber(this.store);
|
||||||
|
|
||||||
console.log(`Created new Excel class in ${selector} with options: ${options}`);
|
console.log(`Created new Excel class in ${selector} with options: ${options}`);
|
||||||
}
|
}
|
||||||
@ -46,10 +49,13 @@ export class Excel {
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
this.$el.append(this.getRoot());
|
this.$el.append(this.getRoot());
|
||||||
|
|
||||||
|
this.subscriber.subscribeComponents(this.components);
|
||||||
this.components.forEach(component => component.init());
|
this.components.forEach(component => component.init());
|
||||||
}
|
}
|
||||||
|
|
||||||
destroy() {
|
destroy() {
|
||||||
|
this.subscriber.unsubscribeFromStore();
|
||||||
this.components.forEach(component => component.destroy());
|
this.components.forEach(component => component.destroy());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,6 +10,7 @@ export class Formula extends ExcelComponent {
|
|||||||
super($root, {
|
super($root, {
|
||||||
listeners: ['input', 'keydown'],
|
listeners: ['input', 'keydown'],
|
||||||
name: 'Formula',
|
name: 'Formula',
|
||||||
|
subscribe: ['currentText'],
|
||||||
...options,
|
...options,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -26,16 +27,13 @@ export class Formula extends ExcelComponent {
|
|||||||
|
|
||||||
this.formulaInput = this.$root.find('#formula-input');
|
this.formulaInput = this.$root.find('#formula-input');
|
||||||
|
|
||||||
// this.$on('table:input', text => {
|
|
||||||
// this.formulaInput.text = text;
|
|
||||||
// });
|
|
||||||
this.$on('table:select-cell', text => {
|
this.$on('table:select-cell', text => {
|
||||||
this.formulaInput.text = text;
|
this.formulaInput.text = text;
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.$subscribe(state => {
|
storeChanged({ currentText = '' }) {
|
||||||
this.formulaInput.text = state.currentText;
|
this.formulaInput.text = currentText;
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onInput(event: Event) {
|
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 { Store } from './createStore';
|
||||||
import { DomListener } from './DomListener';
|
import { DomListener } from './DomListener';
|
||||||
import { Emitter } from './Emitter';
|
import { Emitter } from './Emitter';
|
||||||
@ -6,6 +6,7 @@ import { Emitter } from './Emitter';
|
|||||||
interface ExcelComponentClass {
|
interface ExcelComponentClass {
|
||||||
toHTML: () => string;
|
toHTML: () => string;
|
||||||
prepare: () => void;
|
prepare: () => void;
|
||||||
|
storeChanged?: (args: any) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
type OptionsType = {
|
type OptionsType = {
|
||||||
@ -13,13 +14,15 @@ type OptionsType = {
|
|||||||
name: string;
|
name: string;
|
||||||
emitter?: Emitter;
|
emitter?: Emitter;
|
||||||
store: Store;
|
store: Store;
|
||||||
|
subscribe: string[],
|
||||||
};
|
};
|
||||||
|
|
||||||
export class ExcelComponent extends DomListener implements ExcelComponentClass {
|
export abstract class ExcelComponent extends DomListener implements ExcelComponentClass {
|
||||||
name: string;
|
name: string;
|
||||||
emitter: Emitter;
|
emitter: Emitter;
|
||||||
store: Store;
|
store: Store;
|
||||||
storeSub: SubscribeType;
|
storeSub: SubscribeType;
|
||||||
|
subscribe: string[];
|
||||||
private unsubscribers: ((args?: any) => any)[];
|
private unsubscribers: ((args?: any) => any)[];
|
||||||
|
|
||||||
constructor($root: any, options: OptionsType) {
|
constructor($root: any, options: OptionsType) {
|
||||||
@ -27,6 +30,8 @@ export class ExcelComponent extends DomListener implements ExcelComponentClass {
|
|||||||
this.name = options?.name;
|
this.name = options?.name;
|
||||||
this.emitter = options?.emitter;
|
this.emitter = options?.emitter;
|
||||||
this.store = options?.store;
|
this.store = options?.store;
|
||||||
|
this.subscribe = options?.subscribe;
|
||||||
|
|
||||||
this.unsubscribers = [];
|
this.unsubscribers = [];
|
||||||
this.prepare();
|
this.prepare();
|
||||||
}
|
}
|
||||||
@ -52,8 +57,12 @@ export class ExcelComponent extends DomListener implements ExcelComponentClass {
|
|||||||
this.store.dispatch(action);
|
this.store.dispatch(action);
|
||||||
}
|
}
|
||||||
|
|
||||||
$subscribe(fn: (state?: StateType) => void) {
|
storeChanged(args?: any) {
|
||||||
this.storeSub = this.store.subscribe(fn);
|
console.log('CHANGE STORE: ', args);
|
||||||
|
}
|
||||||
|
|
||||||
|
isWatching(key: string) {
|
||||||
|
return this.subscribe?.includes(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
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() {
|
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;
|
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