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 {
|
||||
constructor(parent, props?: any) {
|
||||
const env = parent instanceof Component ? parent.env : parent;
|
||||
const storeProps = mapStateToProps(env.store.state);
|
||||
props = Object.assign(props || {}, storeProps);
|
||||
super(parent, props);
|
||||
const ownProps = Object.assign({}, props || {});
|
||||
const storeProps = mapStateToProps(env.store.state, ownProps);
|
||||
const mergedProps = Object.assign(props || {}, storeProps);
|
||||
super(parent, mergedProps);
|
||||
this.__widget__.currentStoreProps = storeProps;
|
||||
this.__widget__.ownProps = ownProps;
|
||||
}
|
||||
mounted() {
|
||||
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)) {
|
||||
this.__widget__.currentStoreProps = storeProps;
|
||||
// probably not optimal, will do 2 object.assign, one here and
|
||||
// one in updateProps.
|
||||
const nextProps = Object.assign(
|
||||
{},
|
||||
this.props,
|
||||
this.__widget__.currentStoreProps
|
||||
);
|
||||
this.updateProps(nextProps, false);
|
||||
this.updateProps(ownProps, false);
|
||||
}
|
||||
});
|
||||
super.mounted();
|
||||
@@ -34,8 +30,13 @@ export function connect(mapStateToProps) {
|
||||
super.willUnmount();
|
||||
}
|
||||
updateProps(nextProps, forceUpdate) {
|
||||
nextProps = Object.assign(nextProps, this.__widget__.currentStoreProps);
|
||||
return super.updateProps(nextProps, forceUpdate);
|
||||
this.__widget__.ownProps = nextProps;
|
||||
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> {
|
||||
inlineTemplate = `<div/>`;
|
||||
mounted() {
|
||||
steps.push('child:mounted');
|
||||
steps.push("child:mounted");
|
||||
}
|
||||
willUnmount() {
|
||||
steps.push('child:willUnmount')
|
||||
steps.push("child:willUnmount");
|
||||
}
|
||||
destroyed() {
|
||||
steps.push('child:destroyed');
|
||||
steps.push("child:destroyed");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,16 +142,55 @@ describe("connecting a component to store", () => {
|
||||
const parent = new Parent(env);
|
||||
|
||||
await parent.mount(fixture);
|
||||
expect(steps).toEqual([
|
||||
'child:mounted',
|
||||
]);
|
||||
expect(steps).toEqual(["child:mounted"]);
|
||||
|
||||
await parent.updateState({ child: false });
|
||||
expect(steps).toEqual([
|
||||
'child:mounted',
|
||||
'child:willUnmount',
|
||||
'child:destroyed',
|
||||
"child:mounted",
|
||||
"child:willUnmount",
|
||||
"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