2014-05-15 9 views
7

Ho creato un binding Knockout per poter attivare i layer KML con Google Maps, ma la soluzione sembra un po 'lenta e "sfarfallio". Come posso evitare di ricreare la mappa e i livelli su ogni interruttore?Come attivare/disattivare i layer KML utilizzando Knockout.js senza ricreare la mappa?

Una demo in esecuzione può essere trovato 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()); 

risposta

1

La prima cosa da fare è almeno utilizzare il init callback.

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 

    } 
} 

Poi, nel update richiamata avete solo bisogno di aggiornare la visibilità dei livelli

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

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

     // for each level, set visibility 
    } 
} 

Ma, ora non abbiamo una mappa da utilizzare nel update callback. Per fortuna siamo in grado di creare i nostri oggetti all'interno del nostro bindingHanlder, quindi cerchiamo di fare quello:

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

Questo significa anche che possiamo definire un modello per il nostro livello come bene e lasciare che la visibilità controllo del modello attraverso un osservabile.

Il risultato è il seguente jsFiddle example

Problemi correlati