I have an Office add-in which can open a popup browser window by
popup = window.open("https://localhost:3000/#/new", "popup", "status=1, location=1, width=1000, height=1200")
This page is coded by angular. To enable the communication between the add-in and the popup, I have added a listener in the controller. As a result, they can send messages to each other by postMessage
.
app.controller("Ctrl", ["$scope", "$window", function($scope, $window) {
... ...
$window.addEventListener("message", receiveMessage, false);
}
The communication works, except when the add-in changes the url of the popup to newUrl
(where newUrl
is another page instance which uses the same controller), by
popup.location.href = newUrl
Visually, the popup has changed, however the previous listener is not removed. As a result, one message sent by the add-in is received and treated twice (ie, by the new page and the previous page).
Does anyone know how to properly clean the listener when the add-in changes the popup page?
The comment of Cenk is correct: the event-remove and event-add logic must be in exactly the same function scope.
So, on the side of the add-in, when the popup changes to another Url, I need to send manually a close
message by postMessage
to the page:
popup.postMessage({ "req": "close" }, popup.location.href);
popup.location.href = url
On the side of the popup page, I could remove the listener in the receiveMessage
, because it is still in the same page/function scope:
app.controller("Ctrl", ["$scope", "$window", function($scope, $window) {
... ...
var receiveMessage = function (event) {
... ...
switch (event.data) {
... ...
case "close":
$window.removeEventListener("message", receiveMessage, false)
}
}
}])