stencil
stencil copied to clipboard
bug: events lost when template separated out in another js file, view works
Prerequisites
- [X] I have read the Contributing Guidelines.
- [X] I agree to follow the Code of Conduct.
- [X] I have searched for existing issues that already report this problem, without success.
Stencil Version
2.11.0
Current Behavior
Interesting problem, so please read till the end. what I want to achieve is separating template in another js file and lazyload it when required. This same thing when done in React ecosystem works, but stencil doesn't!
I am having my tsx template in another .js file say
template-three.js has simple onClick which only alerts
import { h } from '@stencil/core';
export const template_three = () => {
return <button onClick={() => alert()}>Template three here</button>;
};
when I try to call this method by importing in component-two.tsx like this
import { Component, Fragment, h, Host, State } from '@stencil/core';
@Component({
tag: 'component-two',
styleUrl: 'component-two.css',
shadow: true,
})
export class ComponentTwo {
@State() showComponentOne: any;
method: any;
template: string = '';
constructor() {}
componentWillRender() {
this.fetchComp(2);
}
// lazy load template when needed based on type passed
fetchComp(type) {
let this_ = this;
switch (type) {
case 0:
import('./template').then(module => {
this.showComponentOne = module.template_one;
});
break;
case 1:
import('./template-two').then(module => {
this.showComponentOne = module.template_two;
});
break;
case 2:
import('./template-three').then(module => {
this.showComponentOne = module.template_three;
);
break;
default:
break;
}
}
clicked() {
alert();
}
methodHere() {}
// check if template received then simply call that method with this attached
render() {
let this_ = this;
return this.showComponentOne ? this.showComponentOne.apply(this) : <div></div>;
}
}
View renders, but event listners are not working :/, not even a simple alert :(. When I inspect, I don’t see any event attached to button. however if same function I keep inside component class, it works :( !!!
check two different objects when template defined inside and outside component.
Can you tell me what I am doing wrong here.
I can’t keep templates in component only cause I have many UI’s for same logic. So far, I didn't get any way on internet this answer doesn't help either https://stackoverflow.com/questions/51984162/passing-custom-template-to-stencil-component
Expected Behavior
Events should get attached not just view.
Steps to Reproduce
written in description sample component and sample template. attached repo for triage.
Code Reproduction URL
https://github.com/pranav-js/triage-repo
Additional Information
React support separating templates out like this, not sure why stencil is loosing events. One thing I found is loss of $elem key in object returned probably by h
Thanks for the issue! This issue has been labeled as holiday triage
. With the winter holidays quickly approaching, much of the Stencil Team will soon be taking time off. During this time, issue triaging and PR review will be delayed until the team begins to return. After this period, we will work to ensure that all new issues are properly triaged and that new PRs are reviewed.
In the meantime, please read our Winter Holiday Triage Guide for information on how to ensure that your issue is triaged correctly.
Thank you!
funny, I found a hack to make it work, but its super super strange and weird !!!!! 😰
I declared a random variable in my component and not event using it 😂. Just attach all events inside this random div tag without any function definition.
randomsds = (<div onClick={() => {}} onInput={() => {}}></div>)
and events inside external file template works now 🎉 .
Whoever reads this from community/helper/experts please explain me why?
next issue: now I have to do same for placeholder, id, style, class, basically attributes (but when I print object) it has
FYI I added a possible explanation (and workaround) on the StackOverflow question.
@tricki that is still adding template1,2,3 in same .js file. with functional component however each one has its own .js file that i can lazy load
@tricki @rwaskiewicz is there a way to store templates in CDN somewhere, since this is JSX I am not sure if I can send it from backend, if so how can i achieve that?
Stencil doesn't have the same functionality that React does when it comes to functional components, which I think may be a part of what we're seeing here. At the very least, I think this is a good candidate where we can improve the documentation around functional components.
At the same time, the behavior we're seeing here (where onClick
isn't firing) isn't intuitive, and should be looked into further when we dynamically import the module. Thanks for the detailed info, and thanks to @tricki for doing additional debugging!