当Google Maps API v3信息窗口关闭时,Knockout会丢失绑定

时间:2013-03-10 01:09:59

标签: google-maps-api-3 knockout.js

我将数据绑定到div,然后我将其设置为InfoWindow的内容。当点击地图上的标记时,我改变了绑定的observable,它更新了信息窗口中的内容。所有这一切都正常,直到信息窗口关闭。谷歌地图从DOM中删除信息窗口,以及我的div,它具有绑定。重新打开信息窗口会导致其内容在其关闭时处于冻结状态。

对observable的任何更改都不再更新ui,包括使用valueHasMutated。我尝试过重置信息窗口的内容并重新绑定,但JQuery元素仍然存在,我得到重复的内容。我也尝试过使用cleanNode和重新绑定,但也获得了重复的内容。

我绑定的div:

<div id="placeTmpl" data-bind="with: place">
        <h3>
            <a data-bind="text: name, attr: { 'href': detailsUrl($data) }"></a>
        </h3>
</div>

Google Maps InfoWindow:

window.infoWindow = new window.google.maps.InfoWindow({
    content: ''
});
window.infoWindow.setContent($('#placeTmpl')[0]);

事件监听器和更新可观察的

window.google.maps.event.addListener(marker, "click", function() {
    window.viewModel.openInfoWindow(marker, data);
});

self.openInfoWindow = function (marker, data) {
   for (var i = 0; i < self.places().length; i++) {
        if (self.places()[i].placeId == data.PlaceId) {
            self.place(self.places()[i]);
        }
    }
    window.infoWindow.open(map, marker);
};

就像我说的,这一切都很有效,直到信息窗口关闭。我正在寻找一种方法来强制淘汰赛再次开始更新ui,或者在信息窗口关闭时清除并重新绑定。

2 个答案:

答案 0 :(得分:3)

我能够通过将InfoWindow内容设置为html字符串而不是DOM节点来解决这个问题。

即:

window.infoWindow.setContent($('#placeTmpl').html());

而不是:

window.infoWindow.setContent($('#placeTmpl')[0]);

通过这样做,具有敲除绑定的html保持不变,而不是被转移到信息窗口,随后在关闭时将其销毁。 Knockout现在像往常一样更新有界DOM元素,我只需在每次点击时使用html字符串更新信息窗口。

如果你试图将淘汰赛绑定放在谷歌地图InfoWindow中,你将会度过一段美好时光。

答案 1 :(得分:1)

我能够解决这个问题而不必在调用setContent时使用字符串。在我的例子中,信息窗口有动态元素,在信息窗口打开时会更新,因此字符串解决方案不会考虑到这一点。

我添加了一个closeclick处理程序,我在其中跟踪传递给信息窗口的原始DOM元素,并在信息窗口取出后将元素添加回正文。这使得淘汰赛很开心,而且信息窗口并不关心。

var $node = $('#placeTmpl');

var infoWindow = new google.maps.InfoWindow({
    content: $node[0]
});

google.maps.event.addListener(infoWindow, "closeclick", function () {
    //google maps will destroy this node and knockout will stop updating it
    //add it back to the body so knockout will take care of it
    $("body").append($node);
});