2014-05-15 12 views
7

Ich habe eine Knockout-Bindung erstellt, um KML-Layer mit Google Maps umschalten zu können, aber die Lösung scheint ein wenig langsam und "flackernd" zu sein. Wie kann ich vermeiden, die Karte und die Ebenen bei jedem Wechsel neu zu erstellen?Wie können Sie KML-Layer mit Knockout.js umschalten, ohne die Karte neu zu erstellen?

kann eine laufende Demo 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()); 

Antwort

1

Die erste, was zu tun ist, zumindest verwenden, um den init Rückruf gefunden werden.

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 

    } 
} 

Dann wird in dem update Rückruf Sie müssen nur die Sichtbarkeit der Schichten

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

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

     // for each level, set visibility 
    } 
} 

Aber jetzt aktualisieren wir in dem update Rückruf nicht eine Karte zu verwenden. Zum Glück können wir unsere eigenen Objekte in unserem bindingHanlder schaffen, so lassen wir das tun:

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

Dies bedeutet auch, wir auch ein Modell für unsere Schicht definieren und dieses Modell Kontrolle Sicht durch eine beobachtbare lassen.

Dies ergibt alle folgenden jsFiddle example