KnockoutJS没有更新dom - 与Googlemaps api进行交互

时间:2017-04-05 19:42:02

标签: javascript google-maps dom knockout.js

我正在使用knockoutJS进行我的udacity课程,我似乎无法更新我的部分DOM。

我正在与Google地图API进行互动。我有一个observableArray,它包含具有一些内容的位置对象以及包含值true或false的“show”元素。 现在observableArray正在更新(它基于标记是否在可见地图的边界内),但是它没有更新我的DOM,它只应该列出可见位置的标记标题。

RelativeLayout

以下是更新这些值的内容

this.locations = ko.observableArray([{
                title: 'Camden Brookwood',
                location: {
                    lat: 33.8027355,
                    lng: -84.3973864
                },
                content: "Camden Brookwood, Rank: 1",
                show: true
            },
            {
                title: 'Monroe Place',
                location: {
                    lat: 33.8092084,
                    lng: -84.370107
                },
                content: "Monroe Place, Rank: 2",
                show: true
            },
            {
                title: 'Capitol Gateway',
                location: {
                    lat: 33.7453517,
                    lng: -84.384106
                },
                content: "Capitol Gateway, Rank: 3",
                show: true
            },
            {
                title: 'Gables 820 West',
                location: {
                    lat: 33.7808463,
                    lng: -84.4162514
                },
                content: "Gables 820 West, Rank: 4",
                show: true
            },
            {
                title: 'Montage Embry Hills',
                location: {
                    lat: 33.8827244,
                    lng: -84.2480548
                },
                content: "Montage Embry Hills, Rank: 5",
                show: true
            }
        ]);

以下是DOM

的相关部分的代码
google.maps.event.addListener(map, 'tilesloaded', function() {
      for(var i = 0; i < locations().length; i++) {
        if(map.getBounds().contains(locations()[i].location))
        locations()[i].show = true;
        else {
          locations()[i].show = false;
        }
      }
  });

我也尝试过使用“if”数据绑定。

2 个答案:

答案 0 :(得分:1)

您所拥有的已经接近工作,您必须确保将标记的show属性绑定到foreach或您在dom上使用的任何内容。

Jsfiddle:https://jsfiddle.net/timh06/659zp473/

基本上,我将你的lat lng转换为谷歌地图LatLng对象,并修复了敲除绑定。

HTML:

<div data-bind="foreach: locations">
  <!-- ko if: show -->
  <h3 data-bind="text: content"></h3>
  <!-- /ko -->
</div>

JS:

// add markers
var markers = [];
for (var i = 0; i < vm.locations().length; i++) {
    var loc = vm.locations()[i];
    var marker = new google.maps.Marker({
        position: loc.location,
        map: map,
        visible: loc.show,
        title: loc.title
    });
    markers.push(marker);
}

google.maps.event.addListener(map, 'idle', function() {
    var bounds = map.getBounds();
    for (var i = 0; i < vm.locations().length; i++) {
        var marker = vm.locations()[i];
        if (bounds.contains(marker.location)) {
            marker.show(true);
        } else {
            marker.show(false);
        }
    }
});

答案 1 :(得分:1)

每个对象中的show属性需要是可观察的,即

ko.observableArray([{
  title: 'Camden Brookwood',
  location: {
    lat: 33.8027355,
    lng: -84.3973864
  },
  content: "Camden Brookwood, Rank: 1",
  show: ko.observable(true)
}])

然后使用

更新它
locations()[i].show(false)

如文档所述......

&#34;关键点:observableArray跟踪数组中的对象,而不是这些对象的状态

简单地将对象放入observableArray并不会使该对象的所有属性本身都可观察到。当然,如果您愿意,您可以观察这些属性,但这是一个独立的选择。 observableArray只跟踪它所拥有的对象,并在添加或删除对象时通知侦听器。&#34;

http://knockoutjs.com/documentation/observableArrays.html