Knockout.js变量虽然我定义它,但未定义

时间:2018-02-03 12:00:23

标签: javascript knockout.js data-binding

您好,我的问题是我定义了一个类Place并且具有属性Name。 我正在我的ViewModel中初始化一个地方数组。 现在,当我转到HTML循环数组时,它告诉我没有定义Name属性。

Chrome DevTools Console

那我缺少什么?

HTML

<ul class="list-unstyled components" data-bind="foreach filterdPlaces">
            <li>
                <a href="#" data-bind="text: Name, click: bounceElement"></a>
            </li>
</ul>

JS

    var Place = function (place) {
    // Place Info to use in view
    var self = this;
    self.Name = place.title;
    self.Location = place.location;
    self.URI = "";
    self.Street = "";
    self.City = "";
    //console.log(self.Name);
    // boolean variable to determine when to set marker
    self.Visible = ko.observable(true);
    // FourSquare API URI
    var FourSquareSearchApiUri = "https://api.foursquare.com/v2/venues/search?ll=" +
        self.Location.lat + "," + self.Location.lng + "&client_id=" + clientID + "&client_secret=" + clientSecret +
        "&v=20180203&query=" + self.Name;
    // Get Request To fetch data from foursquare API
    $.getJSON(FourSquareSearchApiUri)
        .done(function (data) {
            var results = data.response.venues[0];
            //console.log(data, results);
        }).fail(function () {
            alert("Ohh!Snap Some error hapenned with foursquare API, Check Your Network connection and try again!");
        });

    // Constructing InfoWindow HTML
    self.InfoWindowContent = '<div>' +
        '<div>' + self.Name + '</div>' +
        '<div><a href=""></a></div>' +
        '<div>' + self.Street + '</div>' +
        '<div>' + self.City + '</div>' +
        '</div>';
    self.InfoWindow = new google.maps.InfoWindow({ content: self.InfoWindowContent });

    // Marker object
    self.marker = new google.maps.Marker({
        position: new google.maps.LatLng(self.Location.lat, self.Location.lng),
        map: map,
        title: self.Name
    });

    // ShowMarker function
    self.showMarker = ko.computed(function () {
        if (self.Visible() === true) {
            self.marker.setMap(map);
        }
        else {
            this.marker.setMap(null);
        }
        return true;
    }, self);

    // Adding Listener to click event
    self.marker.addListener('click', function () {
        // Setting content of Info window
        self.InfoWindow.setContent(self.InfoWindowContent);
        // Opening Info Window
        self.InfoWindow.open(map, self);
        // Setting Animation bounce
        self.marker.setAnimation(google.maps.Animation.BOUNCE);
        // Setting Time Out To stop marker From Bouncing
        setTimeout(() => {
            self.marker.setAnimation(null);
        }, 2000);
    });

    // Setting trigger Bounce event marker to call from the view
    self.bounceElement = () => {
        google.maps.event.trigger(self.marker, 'click');
    };
}




    // Knockout ViewModel variable
    var ViewModel = function () {
    var self = this;

    // Search Phrase to filter the list
    self.searchPhrase = ko.observable("");

    // List Of places
    self.Places = ko.observableArray([]);

    // Constructor creates a new map - only center and zoom are required.
    map = new google.maps.Map(document.getElementById('map'), {
        center: { lat: 30.165822, lng: 31.424106 },
        zoom: 13
    });

    // Boundary Object to fit locations in the map
    var bounds = new google.maps.LatLngBounds();
    nearByLocaions.forEach((location)=>{
        bounds.extend(location.location);
    })
    // Extend the boundaries of the map for each marker
    map.fitBounds(bounds);

    // Adding all nearByLocations items to Places list to filter them
    nearByLocaions.forEach((location)=>{
        self.Places.push(new Place(location));
    });

    // Filtering functionality based on word bounded to the search box in the 
    view
    self.filterdPlaces = ko.computed(()=>{
        var filteredItem = self.searchPhrase().toLowerCase();
        if(!filteredItem){
            self.Places().forEach((place)=>{
                place.Visible(true);
            });
            return self.Places()
        }
        else {
            return ko.utils.arrayFilter(self.Places(), function(place){
                var placeName = place.Name.toLowerCase();
                var match = (string.search(filteredItem) >= 0);
                place.Visible(match);
                return match;
            });
        }
    }, self);
    console.log(self.filterdPlaces());
};

当然我正在调用ko.applyBindings(new ViewModel());

1 个答案:

答案 0 :(得分:0)

这是我记下的一个错字:

foreach filteredPlaces

虽然它应该是:

foreach: filteredPlaces