Programmatically Construct ViewTemplates with Bindings #6080
-
I'm wondering if it is at all possible to create a |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 8 replies
-
Yes, this is completely possible. At the lowest level, you can instantiate Let me show you a simple example, and then maybe you can provided me a bit more info and we can figure out how to build the full thing. import { html } from "@microsoft/fast-element";
export function createSingleElementTemplate(tagName: string, attributes: Map<string, string>) {
let markup = `<${tagName}`;
for (const [key, value] of attributes) {
markup += ` ${key}="${value}"`;
}
markup += `></${tagName}>`;
return html(markup as any as TemplateStringsArray);
} The trick here is that tagged template functions are just functions. |
Beta Was this translation helpful? Give feedback.
-
Here's a function that will create a template for a single element, with an arbitrary list of attributes that can be strings, bindings, directives, etc. Note: This is using fast-element 2.0. It should be very similar with the current version. export function createSingleElementView<
TSource = any,
TParent = any,
TContext extends ExecutionContext<TParent> = ExecutionContext<TParent> // I think just ExecutionContext in current
>(tagName: string, attributes: Record<string, string | TemplateValue<TSource, TParent, TContext>> = {}) {
const markup = [`<${tagName}`];
const values: TemplateValue<TSource, TParent, TContext>[] = [];
for (const key in attributes) {
markup.push(` ${key}="`);
values.push(attributes[key]);
markup.push(`"`);
}
markup.push(`></${tagName}>`);
return html(markup as any as TemplateStringsArray, values);
}
class Person {
firstName: string;
}
const firstNameEditor = createSingleElementView<Person>("input", {
"type": "text",
":value": x => x.firstName,
"@input": (x, c) => x.firstName = (c.event.target as any).value
});
// use the template and view directly
const view = firstNameEditor.create();
view.bind(new Person(), ExecutionContext.default); // current uses defaultExecutionContext
view.appendTo(someParentElement);
// later
view.remove()
view.unbind();
// Can also be used inside another template...
const template = html<Person>`
First Name: ${firstNameEditor}
`; I haven't tested this... 🤣 |
Beta Was this translation helpful? Give feedback.
Here's a function that will create a template for a single element, with an arbitrary list of attributes that can be strings, bindings, directives, etc.
Note: This is using fast-element 2.0. It should be very similar with the current version.