Created web component using LitElement. I am using this component multiple times in the same page.
I want to trigger one event only when my component is rendering first time on page.
What do you mean by "first time on page"?
If you want the first time any instance renders in the current loaded page set window.someProperty before firing your event and then check it before firing the event again. Anything on window is cleared when the user navigates between pages, but if you're running an SPA (which Lit is particularly well suited to) that might not happen for a while.
If you want to do something the first time the element is loaded you can add the flag to the module that holds the element.
If you want each element to fire an event as it initially renders you can use firstUpdated.
If you want the first element somewhere in the document to fire an event then that's harder, as web components are all about isolated functionality - they aren't aware of other instances on the same page. Your best bet is to either:
Add a parent component that picks up events from all the sub-components and only does something the first time it gets one.
Add an index property that you increment for each instance and only have the event fire when it is 0.
Related
In Vaadin when readding a component that was removed previously will create a new element in the DOM.
Lets look at it in detail
Button button = new Button("test");
button.getElement().executeJs("""
this.addEventListener("click", event => {
alert("hello");
});
""");
add(button);
now after some event on the server we decide to remove the component from the view. So the corresponding element in the DOM gets removed.
then after another event we add the button component again. so vaadin creates a new Element on the client and adds this to the DOM. (the new element is missing the eventlistener)
What I would expect to happen is that vaadin reuses the same element that existed before. But it does not. normally this would not really matter, but in our case we added a eventlistener with js. (yes we could add eventlisteners on the javaside, but let’s suppose that we really need to do it in js because we want to execute some code on the client)
why is vaadin doing this, and is there an option so vaadin uses always the same element.
In pure JS I could easily just create a lookup table with the element that I removed, and then later use the elements in the lookup table to add them again to the DOM. Doing this would keep all the event listeners for the element.
What really perplexes me, is that even though the element in the DOM is different everytime, the Element I get with component.getElement() is always the same. Isn’t this element supposed to represent the element on the clientside?
Of course we could just run the same js on the element everytime we add the element to the view, but that is quite cumbersome.
Is vaadin doing this because of performance reasons. What are your explanations for this behaviour?
This is indeed a mechanism to avoid leaking memory. A mechanism based on server-side reference tracking would be significantly more complex, work with a delay (because the reference is cleared only when GC runs), and make it more difficult for the developer to control what happens. The current design makes it easy for the developer to choose what should happen: hide to preserve it in the browser, detach to let it be garbage collected.
I could also clarify that the same DOM element is reused in cases when the component is detached and then attached back again during the same server visit.
I want to execute a piece of code every time a new the page in navigated to. I am using the <page-router-outlet>.
As mention here, while using page-router-outlet the component is cached. So when it is navigated back into view no Init lifecycle events of angular 2 are executed.
I tied using just the , which does not cache the component and as a result call the Init Lifecycle events. But using it exits the app when I press the Hardware back button.
The site you linked to also mentions this: "What you can do is inject Page inside your component and attach to page navigation events (for example navigatedFrom) and do the cleanup there." Those events are listed here, especially the "navigatedTo" event seems relevant for your usecase.
On a single page app, my problem is I'm subscribing to the hashchange event to render the content (create and destroy widgets that represent my pages), but the function only gets fired when the hash actually changes, such as when the browser back and forward buttons are clicked.
My main javascript file that always gets loaded on first time and also on refresh contain the following
topic.subscribe("/dojo/hashchange", function(newhash){
//set content based on hash
});
When refresh is clicked, it doesn't get fired and I'm left with a blank page (all my logic to render the page lies inside the anonymous function for that topic I subscribed to)
your subscribe isn't being called on a refresh as the hash didn't actually change. you're subscribing to hash changes, changes that happen after the page as loaded.
using this subscribe method things can get out of hand quickly. you may want to look at using route. some links -
https://developer.mozilla.org/en-US/docs/Web/Events/hashchange
https://dojotoolkit.org/documentation/tutorials/1.9/hash/
https://dojotoolkit.org/reference-guide/1.10/dojo/router.html
https://www.sitepen.com/blog/2014/06/18/dojo-faq-does-dojo-have-routing-like-backbone-and-embe/
The default behavior or angularjs/ionic is to remove the DOM element when the route changed/left the page and replace it with the new DOM elm/run the controller again if you navigate back to the previous page.
Is there a way to hide the DOM elm associated to the route instead of removing it completely?
My use case is: my IONIC app landing page/index takes some time to compute/render and when the user navigate to detailed view and come back to the index page it build it again from scratch, because the DOM was removed and it needs to build again, which is a waist of time so rather than removing the DOM elm when the route changed hide it instead and if the user come back to the previous route, show it. this will definitely improve the app performance.
Looking forward to your response.
Thanks in advance
Abod
Use tabs in your project: http://ionicframework.com/docs/api/directive/ionNavView/
There is a lot of stuff to understand but this feature works great.
Basicly it allows you to change view without removing DOM (it stores it in memory). When you come back to previous DOM it's just loaded from memory.
I am in the process of creating a huge web application, with a JavaScript based UI, and many events generated continuously.
To avoid bad performance due to the huge amount of the event listeners needed, I of course opted to use a single event listener which will catch all the events generated from the children elements (event bubbling).
The problem is, this application is designed in such a way that one or more modules can be loaded into the main JavaScript library I'm coding (which is responsible for controlling the UI and every other aspect of the program). Of course every module should be completely independent from each other, so you can choose which methods to load, without affecting the general functionality of the library, only adding or removing features.
Since every module can operate in different DOM elements, I need to have at least a single event listener for each module, since two modules can listen for events generated by html elements placed in different DOM branches.
http://jsfiddle.net/YRejF/2/
In this fiddle for example, the first button will let the first paragraph trigger an event, and its parent will catch it. The second button will let the second paragraph fire the event, but the div listening for the same event won't catch it, because it's not fired from one of its sons.
So my question is: is it possible to have a single event listener, able to listen also to events triggered from elements that are not its sons (elements placed everywhere on the page)?
I was thinking about having a js object, or a dom node, which store the data of the element which triggered the event, and the event itself, then a general event will be fired on the global event listener (no matter where it's placed in the dom), and it will then read the data to discover which element generated which event, and act accordingly.
Any help or suggestion about better ways of achieving this?
jQuery has a special binder for this kind of cases: live(). It let's all events bubble to the document and then handles them accordingly. However, if you use div or other containers for different panels etc, maybe using delegate() makes more sense. Don't worry too much about the number of bound elements. Believe me, it will run as well with 50 binds or 10 delegates as it will with 1 live.