widget: add t-key option, add better error handling

This commit is contained in:
Géry Debongnie
2019-01-30 11:29:54 +01:00
parent 145dc9b5d7
commit c0c7414b18
4 changed files with 78 additions and 4 deletions
+13 -2
View File
@@ -142,11 +142,22 @@ export class Widget<T extends WEnv, Props> {
}
/**
* Note: it is ok to call updateState before the widget is started. In that
* This is the safest update method for widget: its job is to update the state
* and rerender (if widget is mounted).
*
* Notes:
* - it checks if we do not add extra keys to the state.
* - it is ok to call updateState before the widget is started. In that
* case, it will simply update the state and will not rerender
*/
async updateState(nextState: Object) {
Object.assign(this.state, nextState);
for (let key in nextState) {
if (key in this.state) {
this.state[key] = nextState[key];
} else {
throw new Error(`Invalid key: '${key}' does not exist in widget state`);
}
}
if (this.__widget__.isStarted) {
return this.render();
}
+15 -1
View File
@@ -698,6 +698,10 @@ const widgetDirective: Directive = {
atNodeEncounter({ ctx, value, node, qweb }): boolean {
ctx.rootContext.shouldDefineOwner = true;
let props = node.getAttribute("t-props");
let key = node.getAttribute("t-key");
if (key) {
key = qweb._formatExpression(key);
}
if (props) {
props = props.trim();
if (props[0] === "{" && props[props.length - 1] === "}") {
@@ -718,10 +722,20 @@ const widgetDirective: Directive = {
let defID = ctx.generateID();
let widgetID = ctx.generateID();
ctx.addLine(`let _${dummyID} = {}; // DUMMY`);
let keyID = key && ctx.generateID();
if (key) {
// we bind a variable to the key (could be a complex expression, so we
// want to evaluate it only once)
ctx.addLine(`let key${keyID} = ${key};`);
}
ctx.addLine(`let _${dummyID}_index = c${ctx.parentNode}.length;`);
ctx.addLine(`c${ctx.parentNode}.push(_${dummyID});`);
ctx.addLine(`let def${defID};`);
let templateID = ctx.inLoop ? `String(-${widgetID} - i)` : String(widgetID);
let templateID = key
? `key${keyID}`
: ctx.inLoop
? `String(-${widgetID} - i)`
: String(widgetID);
ctx.addLine(
`let w${widgetID} = ${templateID} in context.__widget__.cmap ? context.__widget__.children[context.__widget__.cmap[${templateID}]] : false;`
);
+4 -1
View File
@@ -22,6 +22,9 @@ const template = `
<t t-widget="ColorWidget" t-props="{color: state.color}"/>
<button t-on-click="addNotif(false)">Add notif</button>
<button t-on-click="addNotif(true)">Add sticky notif</button>
<t t-foreach="state.test" t-as="blip">
<t t-widget="Counter" t-key="blip" t-props="{initialState: 100}"/>
</t>
</div>
`;
@@ -29,7 +32,7 @@ export class Discuss extends Widget<Env, {}> {
name = "discuss";
template = template;
widgets = { Clock, Counter, ColorWidget };
state = { validcounter: true, color: "red" };
state = { validcounter: true, color: "red", test: [1, 2, 3] };
mounted() {}
resetCounter(ev: MouseEvent) {