mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
imp: store connect: mapStateToProps receive ownProps
This commit is contained in:
+15
-14
@@ -7,24 +7,20 @@ export function connect(mapStateToProps) {
|
|||||||
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;
|
||||||
const storeProps = mapStateToProps(env.store.state);
|
const ownProps = Object.assign({}, props || {});
|
||||||
props = Object.assign(props || {}, storeProps);
|
const storeProps = mapStateToProps(env.store.state, ownProps);
|
||||||
super(parent, props);
|
const mergedProps = Object.assign(props || {}, storeProps);
|
||||||
|
super(parent, mergedProps);
|
||||||
this.__widget__.currentStoreProps = storeProps;
|
this.__widget__.currentStoreProps = storeProps;
|
||||||
|
this.__widget__.ownProps = ownProps;
|
||||||
}
|
}
|
||||||
mounted() {
|
mounted() {
|
||||||
this.env.store.on("update", this, () => {
|
this.env.store.on("update", this, () => {
|
||||||
const storeProps = mapStateToProps(this.env.store.state);
|
const ownProps = this.__widget__.ownProps;
|
||||||
|
const storeProps = mapStateToProps(this.env.store.state, ownProps);
|
||||||
if (!shallowEqual(storeProps, this.__widget__.currentStoreProps)) {
|
if (!shallowEqual(storeProps, this.__widget__.currentStoreProps)) {
|
||||||
this.__widget__.currentStoreProps = storeProps;
|
this.__widget__.currentStoreProps = storeProps;
|
||||||
// probably not optimal, will do 2 object.assign, one here and
|
this.updateProps(ownProps, false);
|
||||||
// one in updateProps.
|
|
||||||
const nextProps = Object.assign(
|
|
||||||
{},
|
|
||||||
this.props,
|
|
||||||
this.__widget__.currentStoreProps
|
|
||||||
);
|
|
||||||
this.updateProps(nextProps, false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
super.mounted();
|
super.mounted();
|
||||||
@@ -34,8 +30,13 @@ export function connect(mapStateToProps) {
|
|||||||
super.willUnmount();
|
super.willUnmount();
|
||||||
}
|
}
|
||||||
updateProps(nextProps, forceUpdate) {
|
updateProps(nextProps, forceUpdate) {
|
||||||
nextProps = Object.assign(nextProps, this.__widget__.currentStoreProps);
|
this.__widget__.ownProps = nextProps;
|
||||||
return super.updateProps(nextProps, forceUpdate);
|
const mergedProps = Object.assign(
|
||||||
|
{},
|
||||||
|
nextProps,
|
||||||
|
this.__widget__.currentStoreProps
|
||||||
|
);
|
||||||
|
return super.updateProps(mergedProps, forceUpdate);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
+48
-9
@@ -112,13 +112,13 @@ describe("connecting a component to store", () => {
|
|||||||
class Child extends Component<any, any, any> {
|
class Child extends Component<any, any, any> {
|
||||||
inlineTemplate = `<div/>`;
|
inlineTemplate = `<div/>`;
|
||||||
mounted() {
|
mounted() {
|
||||||
steps.push('child:mounted');
|
steps.push("child:mounted");
|
||||||
}
|
}
|
||||||
willUnmount() {
|
willUnmount() {
|
||||||
steps.push('child:willUnmount')
|
steps.push("child:willUnmount");
|
||||||
}
|
}
|
||||||
destroyed() {
|
destroyed() {
|
||||||
steps.push('child:destroyed');
|
steps.push("child:destroyed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,16 +142,55 @@ describe("connecting a component to store", () => {
|
|||||||
const parent = new Parent(env);
|
const parent = new Parent(env);
|
||||||
|
|
||||||
await parent.mount(fixture);
|
await parent.mount(fixture);
|
||||||
expect(steps).toEqual([
|
expect(steps).toEqual(["child:mounted"]);
|
||||||
'child:mounted',
|
|
||||||
]);
|
|
||||||
|
|
||||||
await parent.updateState({ child: false });
|
await parent.updateState({ child: false });
|
||||||
expect(steps).toEqual([
|
expect(steps).toEqual([
|
||||||
'child:mounted',
|
"child:mounted",
|
||||||
'child:willUnmount',
|
"child:willUnmount",
|
||||||
'child:destroyed',
|
"child:destroyed"
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("connect receives ownprops as second argument", async () => {
|
||||||
|
const state = { todos: [{ id: 1, text: "jupiler" }] };
|
||||||
|
let nextId = 2;
|
||||||
|
const mutations = {
|
||||||
|
addTodo(state, text) {
|
||||||
|
state.todos.push({ text, id: nextId++ });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const store = new Store({ state, mutations });
|
||||||
|
|
||||||
|
class TodoItem extends Component<any, any, any> {
|
||||||
|
inlineTemplate = `<span><t t-esc="props.text"/></span>`;
|
||||||
|
}
|
||||||
|
const ConnectedTodo = connect((state, props) => {
|
||||||
|
const todo = state.todos.find(t => t.id === props.id);
|
||||||
|
return todo;
|
||||||
|
})(TodoItem);
|
||||||
|
|
||||||
|
class TodoList extends Component<any, any, any> {
|
||||||
|
inlineTemplate = `<div>
|
||||||
|
<t t-foreach="props.todos" t-as="todo">
|
||||||
|
<t t-widget="ConnectedTodo" t-props="todo"/>
|
||||||
|
</t>
|
||||||
|
</div>`;
|
||||||
|
widgets = { ConnectedTodo };
|
||||||
|
}
|
||||||
|
|
||||||
|
const ConnectedTodoList = connect(state => state)(TodoList);
|
||||||
|
|
||||||
|
(<any>env).store = store;
|
||||||
|
const app = new ConnectedTodoList(env);
|
||||||
|
|
||||||
|
await app.mount(fixture);
|
||||||
|
expect(fixture.innerHTML).toBe("<div><span>jupiler</span></div>");
|
||||||
|
|
||||||
|
store.commit("addTodo", "hoegaarden");
|
||||||
|
await nextTick();
|
||||||
|
expect(fixture.innerHTML).toBe(
|
||||||
|
"<div><span>jupiler</span><span>hoegaarden</span></div>"
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user