如何在不重新创建地图的情况下使用Knockout.js切换KML图层?

时间:2014-05-15 08:02:09

标签: javascript google-maps knockout.js kml polygon

我创建了一个Knockout绑定,可以使用谷歌地图切换KML图层,但解决方案看起来有点慢,并且#34;闪烁"。如何避免在每个切换上重新创建地图和图层?

可以找到正在运行的演示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 个答案:

答案 0 :(得分: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