К сожалению, обработчик событий close
не может быть настроен с помощью объекта InfoboxOptions
, поэтому вы можете рассмотреть реализацию пользовательского HTML Infobox или . обработчик . В следующем примере показано, как сохранить информационное окно открытым после нажатия кнопки закрытия и добавить настраиваемое действие:
Microsoft.Maps.Events.addHandler(infobox, 'click', handleClickInfoBox);
function handleClickInfoBox(e){
var isCloseAction = e.originalEvent.target.className == "infobox-close-img";
if(isCloseAction){
//keep info window open..
e.target.setOptions({visible: true});
//apply some custom actions..
console.log("Close button clicked");
}
}
function loadMapScenario() {
var map = new Microsoft.Maps.Map(document.getElementById("myMap"), {
center: new Microsoft.Maps.Location(47.60357, -122.32945)
});
var infobox = new Microsoft.Maps.Infobox(map.getCenter(), {
title: "Title",
description: "Description",
actions: [
{
label: "Handler1",
eventHandler: function() {
console.log("Handler1");
}
},
{
label: "Handler2",
eventHandler: function() {
console.log("Handler2");
}
},
{
label: "Handler3",
eventHandler: function() {
console.log("Handler3");
}
}
]
});
infobox.setMap(map);
Microsoft.Maps.Events.addHandler(infobox, 'click', handleClickInfoBox);
}
function handleClickInfoBox(e){
var isCloseAction = e.originalEvent.target.className == "infobox-close-img";
if(isCloseAction){
//keep info window open..
e.target.setOptions({visible: true});
//apply some custom actions..
console.log("Close button clicked");
}
}
body{
margin:0;
padding:0;
overflow:hidden;
}
Я не вижу что, будучи круговой зависимостью.
Слушатель ни от чего не зависит.
ListenerImpl зависит от Слушателя и Вещательной компании
Вещательная компания зависит от Слушателя.
Listener
^ ^
/ \
/ \
Broadcaster <-- ListenerImpl
Все стрелки заканчиваются в Listener. Нет никакого цикла. Так, я думаю, что Вы в порядке.
Какой-либо язык ООП? Хорошо. Вот десятиминутная версия в CLOS.
(defclass broadcaster ()
((listeners :accessor listeners
:initform '())))
(defgeneric add-listener (broadcaster listener)
(:documentation "Add a listener (a function taking one argument)
to a broadcast's list of interested parties"))
(defgeneric remove-listener (broadcaster listener)
(:documentation "Reverse of add-listener"))
(defgeneric broadcast (broadcaster object)
(:documentation "Broadcast an object to all registered listeners"))
(defmethod add-listener (broadcaster listener)
(pushnew listener (listeners broadcaster)))
(defmethod remove-listener (broadcaster listener)
(let ((listeners (listeners broadcaster)))
(setf listeners (remove listener listeners))))
(defmethod broadcast (broadcaster object)
(dolist (listener (listeners broadcaster))
(funcall listener object)))
(defclass direct-broadcaster (broadcaster)
((latest-broadcast :accessor latest-broadcast)
(latest-broadcast-p :initform nil))
(:documentation "I broadcast the latest broadcasted object when a new listener is added"))
(defmethod add-listener :after ((broadcaster direct-broadcaster) listener)
(when (slot-value broadcaster 'latest-broadcast-p)
(funcall listener (latest-broadcast broadcaster))))
(defmethod broadcast :after ((broadcaster direct-broadcaster) object)
(setf (slot-value broadcaster 'latest-broadcast-p) t)
(setf (latest-broadcast broadcaster) object))
Lisp> (let ((broadcaster (make-instance 'broadcaster)))
(add-listener broadcaster
#'(lambda (obj) (format t "I got myself a ~A object!~%" obj)))
(add-listener broadcaster
#'(lambda (obj) (format t "I has object: ~A~%" obj)))
(broadcast broadcaster 'cheezburger))
I has object: CHEEZBURGER
I got myself a CHEEZBURGER object!
Lisp> (defparameter *direct-broadcaster* (make-instance 'direct-broadcaster))
(add-listener *direct-broadcaster*
#'(lambda (obj) (format t "I got myself a ~A object!~%" obj)))
(broadcast *direct-broadcaster* 'kitty)
I got myself a KITTY object!
Lisp> (add-listener *direct-broadcaster*
#'(lambda (obj) (format t "I has object: ~A~%" obj)))
I has object: KITTY
К сожалению, Lisp решает большинство проблем шаблона разработки (такой как Ваш) путем избавления от необходимости их.
В отличие от ответа Херма, я действительно вижу цикл. Это не цикл зависимостей, это - ссылочный цикл: LI содержит объект B, объект B содержит (Массив) объект (объекты) LI. Они не освобождают легко и заботятся о потребностях, которые будут взяты, чтобы гарантировать, чтобы они освободили, если это возможно.
Одно обходное решение должно просто иметь LI объектное хранение WeakReference к вещательной компании. Теоретически, если вещательная компания ушла, нет ничего для вычеркивания из списка с так или иначе, таким образом дерегистрация просто проверит, существует ли вещательная компания, чтобы вычеркнуть из списка от и сделать так, если существует.
Я не Java dev, но что-то вроде этого:
public class ListenerImpl implements Listener {
public Foo() {}
public void registerWithBroadcaster(Broadcaster b){ b.register(this); isRegistered = true;}
public void callBack(Object arg) { if (!isRegistered) throw ... else ... }
public void shutDown() { isRegistered = false; }
}
public class Broadcaster {
private final List listeners = new ArrayList();
public void register(Listener lis) { listeners.add(lis); }
public void unregister(Listener lis) {listeners.remove(lis); }
public void broadcast(Object arg) { for (Listener lis : listeners) { if (lis.isRegistered) lis.callBack(arg) else unregister(lis); } }
}
Используйте слабые ссылки для повреждения цикла.
См. этот ответ.
Вот пример в Lua (я использую свой собственный lib ООП здесь, вижу ссылки для 'Возражения' в коде).
Как в примере Mikael Jansson CLOS, Ваш может использовать функции непосредственно, устраняя необходимость определения слушателей (отметьте использование '...', это - varargs Lua):
Broadcaster = Object:subclass()
function Broadcaster:initialize()
self._listeners = {}
end
function Broadcaster:register(listener)
self._listeners[listener] = true
end
function Broadcaster:unregister(listener)
self._listeners[listener] = nil
end
function Broadcaster:broadcast(...)
for listener in pairs(self._listeners) do
listener(...)
end
end
При придерживании реализации вот пример, который мог быть записан на любом динамическом языке, который я предполагаю:
--# Listener
Listener = Object:subclass()
function Listener:callback(arg)
self:subclassResponsibility()
end
--# ListenerImpl
function ListenerImpl:initialize(broadcaster)
self._broadcaster = broadcaster
broadcaster:register(this)
end
function ListenerImpl:callback(arg)
--# ...
end
function ListenerImpl:shutdown()
self._broadcaster:unregister(self)
end
--# Broadcaster
function Broadcaster:initialize()
self._listeners = {}
end
function Broadcaster:register(listener)
self._listeners[listener] = true
end
function Broadcaster:unregister(listener)
self._listeners[listener] = nil
end
function Broadcaster:broadcast(arg)
for listener in pairs(self._listeners) do
listener:callback(arg)
end
end