2014-05-15 22 views
7

我創建了一個Knockout綁定,可以使用Google Maps切換KML圖層,但解決方案看起來有點慢並且「閃爍」。我如何避免在每個切換中重新創建地圖和圖層?如何在不重新創建地圖的情況下使用Knockout.js切換KML圖層?

正在運行的演示可以發現here

var ViewModel = function() { 
    var self = this; 

    self.mapOptions = { 
     center: new google.maps.LatLng(60.390791, 5.306396), 
     zoom: 2 
    }; 

    self.levels = [{ 
     text: "Type 1", 
     countries: ko.observableArray([ 
      'https://dl.dropbox.com/u/2873968/countries-kml/afghanistan.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/algeria.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/bahrain.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/burundi.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/ca_republic.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/cameroon.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/chad.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/colombia.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/dr_congo.kml']), 
     isVisible: ko.observable(false) 
    }, { 
     text: "Type 2", 
     countries: ko.observableArray([ 
      'https://dl.dropbox.com/u/2873968/countries-kml/russia.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/sudan.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/syria.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/thailand.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/venezuela.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/yemen.kml', 
      'https://dl.dropbox.com/u/2873968/countries-kml/zimbabwe.kml']), 
     isVisible: ko.observable(true) 
    }]; 
}; 

ko.bindingHandlers.KML = { 
    update: function (element, valueAccessor) { 
     var data = ko.utils.unwrapObservable(valueAccessor()), 
      mapOptions = ko.utils.unwrapObservable(data.mapOptions) || {}, 
      levels = ko.utils.unwrapObservable(data.levels) || [], 
      map = new google.maps.Map(element, mapOptions); 

     for (var i = 0; i < levels.length; i++) { 
      var level = levels[i], 
       isVisible = level.isVisible(), 
       text = level.text, 
       countries = ko.utils.unwrapObservable(level.countries) || []; 

      for (var y = 0; y < countries.length; y++) { 
       var country = countries[y], 
        layer = new google.maps.KmlLayer(country, { 
         map: map, 
         preserveViewport: true 
        }); 

       if (isVisible) { 
        layer.setMap(map); 
       } else { 
        layer.setMap(null); 
       } 

      } 
     } 
    } 
}; 

ko.applyBindings(new ViewModel()); 

回答

1

首先要做的是,至少使用init回調。

ko.bindingHandlers.KML = { 
    init: function (element, valueAccessor) { 
     var data = ko.utils.unwrapObservable(valueAccessor()), 
      mapOptions = ko.utils.unwrapObservable(data.mapOptions) || {}, 
      levels = ko.utils.unwrapObservable(data.levels) || [], 
      map = new google.maps.Map(element, mapOptions); 

     // now that the map is created, create layers for each level in each country 

     // set the layers visibility 

    } 
} 

然後,在update回調,你只需要更新層

ko.bindingHandlers.KML = { 
    init: function (element, valueAccessor) { 

    }, 
    update: function(element, valueAccessor){ 
     // get data from valueAccessor 

     // for each level, set visibility 
    } 
} 

但是,知名度,現在我們沒有地圖在update回調使用。幸運的是我們可以把我們bindingHanlder內創造我們自己的對象,所以讓我們做到這一點:

ko.bindingHandlers.KML = { 
    config : { 
     map: {} 
    }, 
    init: function (element, valueAccessor) { 
     var map = new google.maps.Map(element, mapOptions); 

     // now we can store our map; 
     ko.bindingHandlers.KML.config.map = map; 

    }, 
    update: function(element, valueAccessor){ 
     // and use it in the update 
     var map ko.bindingHandlers.KML.config.map; 
    } 
} 

這也意味着我們可以定義我們的層模型,以及讓通過一個可觀察模型對照知名度。

這一切結果如下jsFiddle example

相關問題