掲示板

Want to send only one A.io.request, but somehow it sends multiple

7年前 に Dávid Matejkov によって更新されました。

Want to send only one A.io.request, but somehow it sends multiple

New Member 投稿: 18 参加年月日: 15/12/15 最新の投稿
Hi everybody,

I work on Liferay 7 portlet project. Technologically it is very similar to staging-bar-web portlet. I created new ProductNavigationControlMenuEntry Component class, where I control when to show jsp file specified in method getIconJspPath. In that jsp file I use <liferay-portlet:runtime tag to display my portlet. Everything works great.

In my portlet I set JavaScript event listener using this line of code:
window.addEventListener('click', someFunction, false);

and someFunction looks like this:

<portlet:actionurl name="someName" var="someURL" />
function someFunction(event) {
		event.preventDefault();
				
		A.io.request(
			'&lt;%= someURL %&gt;',
			{
				data: {
					<portlet:namespace />someId: someId,					 
				}
			}
		);
}


Sending A.io.request works good, but the problem is that when I click on pages on site the A.io.request is sent multiple times, depending on how many pages I clicked on that site.

For example when I am only on main (Welcome) page it sends 1 request after clicking. When I navigate from Welcome page to other page on that site, from that moment it starts to send 2 requests and so on and so on, sending 3, 4 ... requests. I noticed that this happens only when I add event listeners for objects like window, body, document. When I add event listener to button in my portlet it sends only 1 request no matter how many pages I visited. I don't know but it looks like problem is sennajs or something like that because when I set event listener to <div> element with id "wrapper" it sends only 1 request too.
thumbnail
7年前 に Olaf Kock によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple (回答)

Liferay Legend 投稿: 6403 参加年月日: 08/09/23 最新の投稿
Dávid Matejkov:
In my portlet I set JavaScript event listener using this line of code:
window.addEventListener('click', someFunction, false);

and someFunction looks like this:
...

...
I don't know but it looks like problem is sennajs or something like that because when I set event listener to <div> element with id "wrapper" it sends only 1 request too.


Confirmed: The Single Page Application (almost sennajs) keeps the page loaded and just replaces some diffs. Thus, if you add yet another eventlistener unconditionally, you end up with one more per intercepted page reload, piling up.
7年前 に Dávid Matejkov によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple

New Member 投稿: 18 参加年月日: 15/12/15 最新の投稿
Thank you so much, it helped me a lot.

Now I use:
window.onclick = function(event) {
      someFunction(event);
}

It only sets one listener no matter how many pages I visited.
thumbnail
7年前 に Olaf Kock によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple

Liferay Legend 投稿: 6403 参加年月日: 08/09/23 最新の投稿
Dávid Matejkov:
Now I use:
window.onclick = function(event) {
      someFunction(event);
}

It only sets one listener no matter how many pages I visited.


Just be aware: If two portlets use the same trick, one will win - they'll step on each other's toes...

I'm guessing that there's a better way, but I keep my hands away from Javascript as much as I can - thus I won't claim to know best practices. Hopefully someone can step in and provide the perfect solution
7年前 に Dávid Matejkov によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple

New Member 投稿: 18 参加年月日: 15/12/15 最新の投稿
Thank you for this advice. It is very useful to know.
thumbnail
7年前 に Chema Balsas によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple

Regular Member 投稿: 127 参加年月日: 13/02/25 最新の投稿
Hey Dávid, as Olaf pointed out, the right approach is for your portlet to clean after himself when a navigation is detected.

Check the Detaching Global Listeners section of the Automatic Single Page Application tutorial for some additional information on this.

As stated, you can use Liferay.on('destroyPortlet', clearPortletHandlers); to trigger your cleanup code.
7年前 に Dávid Matejkov によって更新されました。

RE: Want to send only one A.io.request, but somehow it sends multiple

New Member 投稿: 18 参加年月日: 15/12/15 最新の投稿
Hi, thank you