mirror of
https://github.com/odoo/owl.git
synced 2025-10-06 19:59:41 +07:00
[IMP] slots: via prop 'slots'
The slot inner working has been reworked. A prop "slots" is now passed
explicitely to the component. It looks like
{ slotName_1: slotInfo_1, ..., slotName_m: slotInfo_m }
with the objects slotInfo_i with mandatory keys "__render", "__ctx",
and optional key "__scope" and possibly others.
Here is how a slotInfo object can be created:
A slotInfo object is normally created by setting in a template something
like
<div>
<t t-set-slot="foo" t-set-scope="scope" param_1="var" param_2="3">
content
<t t-esc="scope.bool"/>
<t t-esc="scope.num"/>
</t>
</div>
and it will be used somewhere like
<div>
<t t-esc="props.slots.foo.param_1"/>
<t t-slot="foo" bool="other_var" num="5">
</div>
In the above example, the function "__render" produces the block dom
element for the content of the t-set-slot.
The context "__ctx" will have a key "scope" with value { bool: ..., num: 5 }
and "__scope" will be set to "scope".
This commit is contained in:
committed by
Aaron Bohy
parent
7143dd3ff5
commit
a073568667
+32
-5
@@ -118,12 +118,13 @@ export interface ASTComponent {
|
||||
isDynamic: boolean;
|
||||
dynamicProps: string | null;
|
||||
props: { [name: string]: string };
|
||||
slots: { [name: string]: AST };
|
||||
slots: { [name: string]: { content: AST; attrs?: { [key: string]: string }; scope?: string } };
|
||||
}
|
||||
|
||||
export interface ASTSlot {
|
||||
type: ASTType.TSlot;
|
||||
name: string;
|
||||
attrs: { [key: string]: string };
|
||||
defaultContent: AST | null;
|
||||
}
|
||||
|
||||
@@ -593,7 +594,7 @@ function parseTCall(node: Element, ctx: ParsingContext): AST | null {
|
||||
if (ast && ast.type === ASTType.TComponent) {
|
||||
return {
|
||||
...ast,
|
||||
slots: { default: tcall },
|
||||
slots: { default: { content: tcall } },
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -741,6 +742,11 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
|
||||
// named slots
|
||||
const slotNodes = Array.from(clone.querySelectorAll("[t-set-slot]"));
|
||||
for (let slotNode of slotNodes) {
|
||||
if (slotNode.tagName !== "t") {
|
||||
throw new Error(
|
||||
`Directive 't-set-slot' can only be used on <t> nodes (used on a <${slotNode.tagName}>)`
|
||||
);
|
||||
}
|
||||
const name = slotNode.getAttribute("t-set-slot")!;
|
||||
|
||||
// check if this is defined in a sub component (in which case it should
|
||||
@@ -762,14 +768,27 @@ function parseComponent(node: Element, ctx: ParsingContext): AST | null {
|
||||
slotNode.remove();
|
||||
const slotAst = parseNode(slotNode, ctx);
|
||||
if (slotAst) {
|
||||
slots[name] = slotAst;
|
||||
const slotInfo: any = { content: slotAst };
|
||||
const attrs: { [key: string]: string } = {};
|
||||
for (let attributeName of slotNode.getAttributeNames()) {
|
||||
const value = slotNode.getAttribute(attributeName)!;
|
||||
if (attributeName === "t-slot-scope") {
|
||||
slotInfo.scope = value;
|
||||
continue;
|
||||
}
|
||||
attrs[attributeName] = value;
|
||||
}
|
||||
if (Object.keys(attrs).length) {
|
||||
slotInfo.attrs = attrs;
|
||||
}
|
||||
slots[name] = slotInfo;
|
||||
}
|
||||
}
|
||||
|
||||
// default slot
|
||||
const defaultContent = parseChildNodes(clone, ctx);
|
||||
if (defaultContent) {
|
||||
slots.default = defaultContent;
|
||||
slots.default = { content: defaultContent };
|
||||
}
|
||||
}
|
||||
return { type: ASTType.TComponent, name, isDynamic, dynamicProps, props, slots };
|
||||
@@ -783,9 +802,17 @@ function parseTSlot(node: Element, ctx: ParsingContext): AST | null {
|
||||
if (!node.hasAttribute("t-slot")) {
|
||||
return null;
|
||||
}
|
||||
const name = node.getAttribute("t-slot")!;
|
||||
node.removeAttribute("t-slot");
|
||||
const attrs: { [key: string]: string } = {};
|
||||
for (let attributeName of node.getAttributeNames()) {
|
||||
const value = node.getAttribute(attributeName)!;
|
||||
attrs[attributeName] = value;
|
||||
}
|
||||
return {
|
||||
type: ASTType.TSlot,
|
||||
name: node.getAttribute("t-slot")!,
|
||||
name,
|
||||
attrs,
|
||||
defaultContent: parseChildNodes(node, ctx),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user