【问题标题】:KnockoutJS not updating the dom - interacting with Googlemaps apiKnockoutJS 不更新 dom - 与 Googlemaps api 交互
【发布时间】:2017-04-06 06:48:22
【问题描述】:

我在 udacity 课程中使用了 knockoutJS,但我似乎无法更新我的 DOM 的一部分。

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

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
            }
        ]);

这是更新这些值的内容

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;
        }
      }
  });

这是 DOM 相关部分的代码

<div data-bind="foreach: locations">
      <div class="mini-container" data-bind="visible: show">
        <div data-bind="text: show"></div>
      </div>
    </div>

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

【问题讨论】:

    标签: javascript google-maps dom knockout.js


    【解决方案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)
    

    如文档所述...

    "关键点:一个 observableArray 跟踪数组中有哪些对象,而不是那些对象的状态

    仅仅将一个对象放入 observableArray 并不能使该对象的所有属性本身都可观察。当然,如果您愿意,您可以使这些属性可观察,但这是一个独立的选择。 observableArray 只是跟踪它持有哪些对象,并在添加或删除对象时通知侦听器。”

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

    【讨论】:

      【解决方案2】:

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

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

      基本上,我将您的 lat lng 转换为 google maps 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);
              }
          }
      });
      

      【讨论】:

      • 哦,不,这不是我想要做的。我在地图左侧有一个列表,我想在列表中显示标记位置的名称。
      猜你喜欢
      • 1970-01-01
      • 2022-06-20
      • 2021-11-11
      • 1970-01-01
      • 1970-01-01
      • 2014-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多