mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
+1
-1
@@ -11,7 +11,7 @@ export interface Env {
|
|||||||
qweb: QWeb;
|
qweb: QWeb;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Meta<T extends Env, Props> {
|
export interface Meta<T extends Env, Props> {
|
||||||
readonly id: number;
|
readonly id: number;
|
||||||
vnode: VNode | null;
|
vnode: VNode | null;
|
||||||
isStarted: boolean;
|
isStarted: boolean;
|
||||||
|
|||||||
+32
-22
@@ -1,4 +1,4 @@
|
|||||||
import { Component } from "./component";
|
import { Component, Env } from "./component";
|
||||||
import { EventBus } from "./event_bus";
|
import { EventBus } from "./event_bus";
|
||||||
import { Observer } from "./observer";
|
import { Observer } from "./observer";
|
||||||
|
|
||||||
@@ -6,11 +6,14 @@ import { Observer } from "./observer";
|
|||||||
// Store Definition
|
// Store Definition
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type Mutation = ({state, commit, set}, payload: any) => void;
|
||||||
|
type Action = ({commit, state, dispatch, env}, payload: any) => void;
|
||||||
|
|
||||||
interface StoreConfig {
|
interface StoreConfig {
|
||||||
env?: any;
|
env?: Env;
|
||||||
state?: any;
|
state?: any;
|
||||||
actions?: any;
|
actions?: {[name: string]: Action};
|
||||||
mutations?: { [name: string]: any };
|
mutations?: { [name: string]: Mutation };
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StoreOption {
|
interface StoreOption {
|
||||||
@@ -46,7 +49,7 @@ export class Store extends EventBus {
|
|||||||
this.set = this.observer.set.bind(this.observer);
|
this.set = this.observer.set.bind(this.observer);
|
||||||
}
|
}
|
||||||
|
|
||||||
dispatch(action, payload?: any): Promise<void> | void {
|
dispatch(action: string, payload?: any): Promise<void> | void {
|
||||||
if (!this.actions[action]) {
|
if (!this.actions[action]) {
|
||||||
throw new Error(`[Error] action ${action} is undefined`);
|
throw new Error(`[Error] action ${action} is undefined`);
|
||||||
}
|
}
|
||||||
@@ -67,7 +70,7 @@ export class Store extends EventBus {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commit(type, payload?: any) {
|
commit(type: string, payload?: any): any {
|
||||||
if (!this.mutations[type]) {
|
if (!this.mutations[type]) {
|
||||||
throw new Error(`[Error] mutation ${type} is undefined`);
|
throw new Error(`[Error] mutation ${type} is undefined`);
|
||||||
}
|
}
|
||||||
@@ -117,6 +120,11 @@ function deepRevNumber<T extends Object>(o: T): number {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Constructor<T> = new (...args: any[]) => T;
|
||||||
|
interface EnvWithStore extends Env {
|
||||||
|
store: Store;
|
||||||
|
}
|
||||||
|
|
||||||
export function connect(mapStateToProps, options: any = {}) {
|
export function connect(mapStateToProps, options: any = {}) {
|
||||||
let hashFunction = options.hashFunction || null;
|
let hashFunction = options.hashFunction || null;
|
||||||
|
|
||||||
@@ -144,7 +152,9 @@ export function connect(mapStateToProps, options: any = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(Comp) {
|
return function<E extends EnvWithStore, P, S>(
|
||||||
|
Comp: Constructor<Component<E, P, S>>
|
||||||
|
) {
|
||||||
return class extends Comp {
|
return class extends Comp {
|
||||||
constructor(parent, props?: any) {
|
constructor(parent, props?: any) {
|
||||||
const env = parent instanceof Component ? parent.env : parent;
|
const env = parent instanceof Component ? parent.env : parent;
|
||||||
@@ -152,9 +162,9 @@ export function connect(mapStateToProps, options: any = {}) {
|
|||||||
const storeProps = mapStateToProps(env.store.state, ownProps);
|
const storeProps = mapStateToProps(env.store.state, ownProps);
|
||||||
const mergedProps = Object.assign({}, props || {}, storeProps);
|
const mergedProps = Object.assign({}, props || {}, storeProps);
|
||||||
super(parent, mergedProps);
|
super(parent, mergedProps);
|
||||||
this.__owl__.ownProps = ownProps;
|
(<any>this.__owl__).ownProps = ownProps;
|
||||||
this.__owl__.currentStoreProps = storeProps;
|
(<any>this.__owl__).currentStoreProps = storeProps;
|
||||||
this.__owl__.storeHash = hashFunction(
|
(<any>this.__owl__).storeHash = hashFunction(
|
||||||
{
|
{
|
||||||
state: env.store.state,
|
state: env.store.state,
|
||||||
storeProps: storeProps,
|
storeProps: storeProps,
|
||||||
@@ -181,10 +191,10 @@ export function connect(mapStateToProps, options: any = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_checkUpdate() {
|
_checkUpdate() {
|
||||||
const ownProps = this.__owl__.ownProps;
|
const ownProps = (<any>this.__owl__).ownProps;
|
||||||
const storeProps = mapStateToProps(this.env.store.state, ownProps);
|
const storeProps = mapStateToProps(this.env.store.state, ownProps);
|
||||||
const options: any = {
|
const options: any = {
|
||||||
currentStoreProps: this.__owl__.currentStoreProps
|
currentStoreProps: (<any>this.__owl__).currentStoreProps
|
||||||
};
|
};
|
||||||
const storeHash = hashFunction(
|
const storeHash = hashFunction(
|
||||||
{
|
{
|
||||||
@@ -196,29 +206,29 @@ export function connect(mapStateToProps, options: any = {}) {
|
|||||||
options
|
options
|
||||||
);
|
);
|
||||||
let didChange = options.didChange;
|
let didChange = options.didChange;
|
||||||
if (storeHash !== this.__owl__.storeHash) {
|
if (storeHash !== (<any>this.__owl__).storeHash) {
|
||||||
didChange = true;
|
didChange = true;
|
||||||
this.__owl__.storeHash = storeHash;
|
(<any>this.__owl__).storeHash = storeHash;
|
||||||
}
|
}
|
||||||
if (didChange) {
|
if (didChange) {
|
||||||
this.__owl__.currentStoreProps = storeProps;
|
(<any>this.__owl__).currentStoreProps = storeProps;
|
||||||
this._updateProps(ownProps, false);
|
this._updateProps(ownProps, false, []);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_updateProps(nextProps, forceUpdate, p?: any) {
|
_updateProps(nextProps, forceUpdate, patchQueue: any[]) {
|
||||||
if (this.__owl__.ownProps !== nextProps) {
|
if ((<any>this.__owl__).ownProps !== nextProps) {
|
||||||
this.__owl__.currentStoreProps = mapStateToProps(
|
(<any>this.__owl__).currentStoreProps = mapStateToProps(
|
||||||
this.env.store.state,
|
this.env.store.state,
|
||||||
nextProps
|
nextProps
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this.__owl__.ownProps = nextProps;
|
(<any>this.__owl__).ownProps = nextProps;
|
||||||
const mergedProps = Object.assign(
|
const mergedProps = Object.assign(
|
||||||
{},
|
{},
|
||||||
nextProps,
|
nextProps,
|
||||||
this.__owl__.currentStoreProps
|
(<any>this.__owl__).currentStoreProps
|
||||||
);
|
);
|
||||||
return super._updateProps(mergedProps, forceUpdate, p);
|
return super._updateProps(mergedProps, forceUpdate, patchQueue);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1646,7 +1646,7 @@ describe("async rendering", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test.only("properly behave when destroyed/unmounted while rendering ", async () => {
|
test("properly behave when destroyed/unmounted while rendering ", async () => {
|
||||||
let def = Promise.resolve();
|
let def = Promise.resolve();
|
||||||
|
|
||||||
class Child extends Widget {
|
class Child extends Widget {
|
||||||
|
|||||||
+1
-1
@@ -141,7 +141,7 @@ describe("basic use", () => {
|
|||||||
|
|
||||||
test("env is given to actions", () => {
|
test("env is given to actions", () => {
|
||||||
expect.assertions(1);
|
expect.assertions(1);
|
||||||
const someEnv = {};
|
const someEnv = <Env>{};
|
||||||
const actions = {
|
const actions = {
|
||||||
someaction({ env }) {
|
someaction({ env }) {
|
||||||
expect(env).toBe(someEnv);
|
expect(env).toBe(someEnv);
|
||||||
|
|||||||
Reference in New Issue
Block a user