Liferay IPC listener runs multiple times

时间:2016-11-09 08:29:44

标签: liferay ipc liferay-7

First of all sorry if this question has been already asked somewhere, but after a few hours on google I still can't find an answer.

I am pretty new in portlet development, (but we have a shortage of developers and I have to work with it time to time), so the solution might be something trivial, but I really don't have enough experience with it.

The problem is I have two portlets on a page and I try to let one of them know about changes in the other. For this I use IPC. In the first one I have a Liferay.fire function:

function fire(key,value){
    Liferay.fire(
        'category',{
            id: key,
            name: value
         }
    );
}

In the other I have a Liferay.on('category',function(category){...}) function with an ajax call inside and some rendering methods.

Now if I visit the mentioned page and click on the corresponding buttons, at first everything works just fine. However, if I navigate from this page and come back, the listener will run two times. Navigating again -> three times. And so on... But if I reload the page (with F5 or CTRL+F5), it starts over, so until further navigation the listener runs only once.

The other strange thing is no matter how many times the function runs, the input parameters are all the same for each.

For example, if I have left the page and went back to it 3 times and last time I chose the category with 'id=1', then the function will run 3 times with 'id=1'. Now if I choose 'id=2' it will run 3 times with 'id=2'.

If anyone has any idea I would be really grateful as I am stuck for almost a day now.

Thank you very much in advance and please let me know if you need any further info.

1 个答案:

答案 0 :(得分:3)

您遇到的问题是由正在创建但从未删除的全局Liferay.on侦听器引起的。

在Liferay Portal 7.x中,默认情况下启用SPA导航。这意味着在您导航时,页面不会被完全刷新,而只是使用来自服务器的新数据进行更新。

在传统的导航方案中,每个页面刷新都会重置所有内容,因此您不必对所留下的所有内容保持谨慎。但是,在SPA方案中,Liferay.onLiferay.after或正文代表等全局侦听器可能会出现问题。每次执行该代码时,您都会向全局持久化Liferay对象添加另一个侦听器。结果是观察到这些监听器的多次调用。

要修复它,您只需要听取导航事件,以便像这样分离您的听众:

var onCategory = function(event) {...};

var clearPortletHandlers = function(event) {
    if (event.portletId === '<%= portletDisplay.getRootPortletId() %>') {
        Liferay.detach('onCategoryHandler', onCategory);
        Liferay.detach('destroyPortlet', clearPortletHandlers);
    }
};


Liferay.on('category', onCategory);
Liferay.on('destroyPortlet', clearPortletHandlers);