Here's an example
// my-tempate.js
export default `<button on-click="${() => this.click()}"
````
//index.js
import { LitElement, html } from '@polymer/lit-element';
import template from './my-template.js
export default class Login extends connect(store)(LitElement) {
constructor() {
super();
}
_render() {
return html`${template}`;
}
_stateChanged(state) {
console.log(state);
}
click() {
console.log('i m here');
this.dispatchEvent(new CustomEvent('click'));
}
In this scenario it render the html as *string*
and if I change render function to
_render() {
return html([${template}]);
}
```
Then in this case it render the html page but on click function doesn't work.
And I don't to put html in same js file, it clutter more in terms of codewise.I want to make it as small module like the way we do it in react,angular.
How can we achieve import of html with all function working that are define in html?
I believe you should export TemplateResult from the start:
// my-tempate.js
export default html`<button on-click="${() => this.click()}">Click me</button>`;
Some details.
Then in this case it render the html page but on click function doesn't work.
It won't work anyway. It is because simple template literal just converts your () => this.click() to a string. It will work properly if and only if you use html tag on template literal.
() => this.click()
This part won't work as well if you move declaration to a separate file. this will be undefined because it consumes the root scope which is undefined for ES2015 modules.
Things I mentioned above means that lit-html is designed to be a replacement for JSX. If you want to call component methods in the template you cannot use lit-html outside of your component as well as you cannot use JSX outside of React (and derivatives). The only one approach I can imagine is to export a function that receives arguments and applies them to a html template but I don't think it is a good approach since it creates unnecessary complexity.
export default (onClick) => html`<button on-click="${onClick}">Click me</button>`;
@Lodin this context will change, it will not take Login click function
It will throw an error click is not defined and passing this context to a function will create unnecessary complexity rather than bind to this like we do in React
and I don't want to do:-
_render() {
return template.call(this);
}
You might try something like this: https://glitch.com/edit/#!/zinc-needle?path=template.js:6:51
Here I've update the template.js to export a standard function that returns a TemplateResult and looks like:
import {html} from '@polymer/lit-element';
export function template() {
return html`<style> .mood { color: green; } </style>
Web Components are <span class="mood">${this.mood}</span>!
<button on-click="${() => this._click()}">Change mood</button>`;
}
And I'm matched the _render function with a template getter that binds the remote template to the local scope like so:
get template() {
return template.bind(this)();
}
_render() {
return html`${this.template}`;
}
This is of course is complexity that you could take or leave, but the getter gives you a clean accessor to cache the bound template locally if you're interested in that sort of thing.
Thanks for the suggestion @Westbrook , this approach is more clean.Hopefully they will introduce a feature to modularize html as template export/import
That conversation is definitely ongoing and the powers of it matched with the Template Instantiation Spec are pretty exciting.
Can this be closed now?
Most helpful comment
You might try something like this: https://glitch.com/edit/#!/zinc-needle?path=template.js:6:51
Here I've update the
template.jsto export a standard function that returns a TemplateResult and looks like:And I'm matched the
_renderfunction with atemplategetter that binds the remote template to the local scope like so:This is of course is complexity that you could take or leave, but the getter gives you a clean accessor to cache the bound template locally if you're interested in that sort of thing.