将KnockoutJS绑定到Google Maps InfoWindow内容 [英] Binding KnockoutJS to Google Maps InfoWindow content

查看:130
本文介绍了将KnockoutJS绑定到Google Maps InfoWindow内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我使用Google Maps InfoWindow显示位置详情的项目中,我遇到了敲除绑定的问题。我已经将所选位置的数据绑定到了InfoWindow的HTML内容中,这似乎在开始时运行良好。



现在的问题是:InfoWindow关闭后(例如按下x按钮),google maps 完全移除html内容从信息窗口再次显示(例如,当下一个标记被点击时),从DOM再次添加它。



这里的问题是,该元素从DOM中移除后,内容不再更新。

任何想法我可以重新应用绑定到这个确切的元素?调用ko.applyBindings()再次导致异常您不能将绑定多次应用于同一元素。



这里InfoWindow内容的HTML元素:

 < div id =info-contentdata-bind =if:selectedPlace> 
< div class =gm -iw gm-smdata-bind =with:selectedPlace>
< div class =gm-titledata-bind =text:name>< / div>
< div class =gm-basicinfo>
< div class =gm-addrdata-bind =text:vicinity>< / div>
< div class =gm-websitedata-bind =if:website>< a target =_ blankdata-bind =attr:{href:website} >< / A>< / DIV>
< div class =gm-phonedata-bind =text:formatted_phone_number>< / div>
< / div>
< div class =gm-rev>
< span data-bind =if:rating>
< span class =gm-numeric-revdata-bind =text:rating>< / span>
< div class =gm-stars-b>
< div class =gm-stars -fdata-bind =style:{width:getStarWidth}>< / div>
< / div>
< / span>
< / div>
< / div>

JS初始化函数和onClick函数:

  //在ko.applyBindings(model)
之后调用initialize函数ViewModel.prototype.initialize = function(){

... code初始化映射和搜索元素

//实例化一个InfoWindow
infoWindow = new google.maps.InfoWindow();
infoWindow.setContent(document.getElementById('info-content'));

...

}

//获取搜索返回的每个地方的名称,
// koPlace是淘汰赛对于由搜索返回的地方可观察到,
// i是搜索结果的索引
函数addMarker(koPlace,i){

//创建标记
var m = new google.maps.Marker({
title:koPlace.name(),
position:koPlace.jsPlace.geometry.location,
animation:google.maps.Animation .DROP,
});
m.koPlace = koPlace;
koPlace.marker = m;
标记[i] = m;

google.maps.event.addListener(m,'click',markerClicked);
setTimeout(dropMarker(i),i * 100);
}

function markerClicked(){
var koPlace = this.koPlace; // this引用标记对象

if(koPlace){//只检查
koPlace.selected(true); //这是用于突出显示。
model.selectedPlace(koPlace); //这应该设置绑定。
infoWindow.open(map,this);
}
}


解决方案

I认为我会为我已经使用的这个问题添加另一个解决方案。



您可以设置内容字符串(如Nurik所述)并让它保留绑定,但有一个几个额外的步骤。然后您需要使用jQuery将字符串转换为DOM节点并重新应用淘汰赛绑定:

  function makeContent(){
var html ='< div id =info-window-containerstyle =display:none;>'+
'< div id =info-contentdata-bind = if:selectedPlace>'+
'...'+
'< / div>'+
'< / div>';
html = $ parseHTML(html)[0];
返回html;
)}

function addMarker(){
var infoWindow = new google.maps.InfoWindow();
var m = new google.maps.Marker({
title:koPlace.name(),
...
content:makeContent()
});
m.koPlace = koPlace;
koPlace.marker = m;
标记[i] = m;

google.maps.event.addListener(m,'click',function(){
infoWindow.setContent(this.content);
infoWindow.open(map,this );
)};

ko.applyBindings(YourViewModel,m.content);
)}


In a project where I'm using the Google Maps InfoWindow to display details for locations, I have run into problems with knockout binding. I've bound the data of the selected location with knockout the HTML content of the InfoWindow, which seems to work fine in the beginning.

Now the problem: as soon as the InfoWindow is closed (e.g. by pressing the x-button), google maps removes the html content completely from the DOM and adds it again, when the InfoWindow is displayed again (e.g. when the next marker is clicked).

The problem here is, that the binding gets lost as soon as the element is removed from the DOM, so the content doesn't update anymore.

Any idea how i can reapply the binding to this exact element? calling ko.applyBindings() again leads to the exception "You cannot apply bindings multiple times to the same element".

Here the HTML element for the InfoWindow content:

<div id="info-content" data-bind="if:selectedPlace">
  <div class="gm-iw gm-sm" data-bind="with:selectedPlace">
    <div class="gm-title" data-bind="text:name"></div>
    <div class="gm-basicinfo">
      <div class="gm-addr" data-bind="text:vicinity"></div>
      <div class="gm-website" data-bind="if:website"><a target="_blank" data-bind="attr: {href:website}, text:websiteText"></a></div>
      <div class="gm-phone" data-bind="text:formatted_phone_number"></div>
    </div>
    <div class="gm-rev" >
      <span data-bind="if:rating">
        <span class="gm-numeric-rev" data-bind="text:rating"></span>
        <div class="gm-stars-b">
          <div class="gm-stars-f" data-bind="style: { width: getStarWidth } "></div>
        </div>
      </span>
      <span data-bind="if:url"><a target="_blank" data-bind="attr: {href:url}">see more</a></span>
    </div>
  </div>

JS initialize function and onClick function:

// the initialize function gets called after ko.applyBindings(model)
ViewModel.prototype.initialize = function () {

    ... code to initialize map and search elements

    // instantiate an InfoWindow
    infoWindow = new google.maps.InfoWindow();
    infoWindow.setContent(document.getElementById('info-content'));

    ... 

}

// gets called for each place returned by the search, 
// koPlace is the knockout observable for a place returned by the search, 
// i is the index of the search result
function addMarker(koPlace, i) {

    // create a marker
    var m = new google.maps.Marker({
      title: koPlace.name(),
      position: koPlace.jsPlace.geometry.location,
      animation: google.maps.Animation.DROP,
    });
    m.koPlace = koPlace;
    koPlace.marker = m;
    markers[i] = m;

    google.maps.event.addListener(m, 'click', markerClicked);
    setTimeout(dropMarker(i), i * 100);
}

function markerClicked() {
    var koPlace = this.koPlace; // this refers to the marker object

    if (koPlace) { // just checking
        koPlace.selected(true); // this is used for highlighting.
        model.selectedPlace(koPlace); // this should set the binding.
        infoWindow.open(map, this);
    }
}

解决方案

I thought I would add another solution to this problem that I have used.

You can set the content string (as Nurik stated) and have it keep your bindings but there are a couple of extra steps. You then need to use jQuery to convert the string into a DOM node and reapply the knockout bindings:

function makeContent() {
    var html = '<div id="info-window-container" style="display:none;">' +
                    '<div id="info-content" data-bind="if:selectedPlace">' +
                    '...' +
                    '</div>' +
               '</div>';
    html = $parseHTML(html)[0];
    return html;
)}

function addMarker() {
    var infoWindow = new google.maps.InfoWindow();
    var m = new google.maps.Marker({
      title: koPlace.name(),
      ...
      content: makeContent()
    });
    m.koPlace = koPlace;
    koPlace.marker = m;
    markers[i] = m;

    google.maps.event.addListener(m, 'click', function() {
        infoWindow.setContent(this.content);
        infoWindow.open(map,this);
    )};

    ko.applyBindings(YourViewModel, m.content);
)}

这篇关于将KnockoutJS绑定到Google Maps InfoWindow内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆