Knockout JS将值传递给函数

时间:2017-07-12 19:32:18

标签: javascript google-maps knockout.js

我已经阅读了很多类似的主题,但没有一个答案似乎适合我的情况。我正在使用Google Maps API来实现使用敲除数据绑定的显示/隐藏标记功能。使用显示标记,没有问题。但由于我必须将标记变量传递给hideMarkers函数,所以我无法理解这一点。

这是html:

<div class="col-sm-6">
   <input id="hide-listings" type="button" value="Hide Listings" class="btn1 btn-primary text-center" data-bind="click: hideMarkers">
</div>

这是我的ViewModel:

function viewModel() {
    var self = this;
    self.places = ko.observableArray(locations);
    self.address = ko.observable();
    self.city = ko.observable();
    self.title = ko.observable();
    self.id = ko.observable();
    this.markers = ko.observable();
    this.zaddress = ko.observable();
    this.taddress = ko.observable();
    this.paddress = ko.observable();
    this.filter = ko.observable();
    this.visiblePlaces = ko.computed(function() {
        return this.places().filter(function(place) {
            if (!self.filter() || place.title.toLowerCase().indexOf(self.filter().toLowerCase()) !== -1)
                return place;
        });
    }, this);
    //Zooms to a selected marker, open infowindow and displays current weather
    self.zoomToPlace = function() {
        // Initialize the geocoder.
        var geocoder = new google.maps.Geocoder();
        // Get the place.
        var address = this.address;
        var id = this.id;
        var city = this.city;
        var weatherAPIXU = "http://api.apixu.com/v1/current.json?key=453477e8eec14cbc805210143171706&q=" + city;
        $.getJSON(weatherAPIXU, function(data) {
            var forecast = data.current.temp_c;
            $(".weather").html(forecast + '° C');
        });
        // Geocode the address/area entered to get the center. Then, center the map on it and zoom in
        geocoder.geocode({
            address: address,
        }, function(results, status) {
            map.setCenter(results[0].geometry.location);
            map.setZoom(15);
            google.maps.event.trigger(markers[id], 'click');
        });
    };
    self.showListings = function() {
        var bounds = new google.maps.LatLngBounds();
        // Extend the boundaries of the map for each marker and display the marker
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(map);
            bounds.extend(markers[i].position);
        }
        map.fitBounds(bounds);
    };
    // This function takes the input value in the find nearby area text input
    // locates it, and then zooms into that area. This is so that the user can
    // show all listings, then decide to focus on one area of the map.
    self.zoomToArea = function() {
        // Initialize the geocoder.
        var geocoder = new google.maps.Geocoder();
        // Get the address or place that the user entered.
        var zaddress = this.zaddress();
        // Make sure the address isn't blank.
        if (zaddress === '') {
            window.alert('You must enter an area, or address.');
        } else {
            // Geocode the address/area entered to get the center. Then, center the map on it and zoom in
            geocoder.geocode({
                address: zaddress,
            }, function(results, status) {
                if (status == google.maps.GeocoderStatus.OK) {
                    map.setCenter(results[0].geometry.location);
                    map.setZoom(15);
                } else {
                    window.alert(
                        'We could not find that location - try entering a more' +
                        ' specific place.');
                }
            });
        }
    };
    // This function allows the user to input a desired travel time, in
    // minutes, and a travel mode, and a location - and only show the listings
    // that are within that travel time (via that travel mode) of the location
    self.searchWithinTime = function() {
        // Initialize the distance matrix service.
        var distanceMatrixService = new google.maps.DistanceMatrixService();
        var taddress = this.taddress();
        // Check to make sure the place entered isn't blank.
        if (taddress === '') {
            window.alert('You must enter an address.');
        } else {
            hideMarkers(markers);
            // Use the distance matrix service to calculate the duration of the
            // routes between all our markers, and the destination address entered
            // by the user. Then put all the origins into an origin matrix.
            var origins = [];
            for (var i = 0; i < markers.length; i++) {
                origins[i] = markers[i].position;
            }
            var destination = taddress;
            var mode = document.getElementById('mode').value;
            // Now that both the origins and destination are defined, get all the
            // info for the distances between them.
            distanceMatrixService.getDistanceMatrix({
                origins: origins,
                destinations: [destination],
                travelMode: google.maps.TravelMode[mode],
                unitSystem: google.maps.UnitSystem.IMPERIAL,
            }, function(response, status) {
                if (status !== google.maps.DistanceMatrixStatus
                    .OK) {
                    window.alert('Error was: ' + status);
                } else {
                    displayMarkersWithinTime(response);
                }
            });
        }
    };
    // This function fires when the user select "go" on the places search.
    // It will do a nearby search using the entered query string or place.
    self.textSearchPlaces = function() {
        var bounds = map.getBounds();
        var place = this.paddress();
        hideMarkers(placeMarkers);
        var placesService = new google.maps.places.PlacesService(map);
        placesService.textSearch({
            query: place,
            bounds: bounds
        }, function(results, status) {
            if (status === google.maps.places.PlacesServiceStatus
                .OK) {
                createMarkersForPlaces(results);
            }
        });
    };
    // This function will loop through the listings and hide them all.
    this.hideMarkers = function(markers) {
        for (var i = 0; i < markers.length; i++) {
            markers[i].setMap(null);
        }
    };
}
ko.applyBindings(new viewModel());

请告诉我如何最好地解决这个问题,谢谢!

2 个答案:

答案 0 :(得分:1)

如果markersthis.markers,则您无需将标记传递给函数,因为它可用:

this.hideMarkers = function(markers) {
    var m = markers == null ? this.markers : markers;
    for (var i = 0; i < m.length; i++) {
        m[i].setMap(null);
    }
};

这意味着你也可以将标记传递给这个功能,如果你没有,它将默认为你的this.markers

你也可以像这样在淘汰赛中传递额外的参数,如果那就是你所看到的:

<input data-bind="click: hideMarkers.bind($data, markersYouWishtoHide)">

http://knockoutjs.com/documentation/click-binding.html

答案 1 :(得分:1)

我已经弄明白了!问题是我将值传递给viewModel中的函数,但不是在我的click数据绑定中!正确的html:

re.findall(r'(https://example.org/a/(?:([0-9]+)/([0-9a-f]{10})/)|.*)', message)

ViewModel功能很简单:

   <div class="col-sm-6">
     <input id="hide-listings" type="button" value="Hide Listings" class="btn1 btn-primary text-center" data-bind="click: function() {hideMarkers(markers)}">
   </div>