我正在研究KnockoutJS应用程序并尝试实现标记搜索功能。我们的想法是使用名称在搜索栏上执行搜索,并使用列出的显示过滤相应的标记。以下函数执行过滤 -
my.myDataFilter = function(){
my.FilteredList = ko.pureComputed(function() {
if(my.query() === "") {
return my.points;
}
else {
return ko.utils.arrayFilter(my.points(), function(item) {
return item.name().toLowerCase().indexOf(my.query().toLowerCase())>-1;
});
}
}, this);
}
搜索栏位于HTML -
<header>
<form action="#">
<input class="search" placeholder="Search…" type="search" name="q" data-bind="value: my.query, valueUpdate: 'keyup'" autocomplete="off">
</form>
</header>
并可能显示 -
<div class="con">
<h3>Filtered List</h3>
<ul data-bind="template: {name:'beer', foreach: my.FilteredList}">
</ul>
</div>
my.loadMap函数位于 -
之下my.loadMap = function(item){
my.pusMarkerData(item);
}
该功能推送标记数据为 -
my.query = ko.observable("");
my.pusMarkerData = function(item){
// console.log(item);
my.points = ko.observableArray();
for (var j = 0; j < item.length; j++){
my.points.push( new my.mapMarker( item[j]['category'], item[j]['name'], item[j]['lat'], item[j]['lon']));
}
}
我的问题是 -
由于
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>Single page map application</title>
<link rel="stylesheet" type="text/css" href="css/main.css">
</head>
<body>
<header>
<form action="#">
<input class="search" placeholder="Search…" type="search" name="q" data-bind="value: my.query, valueUpdate: 'keyup'" autocomplete="off">
</form>
</header>
<div class="content">
<h3>Complete List</h3>
<ul data-bind="template: {name:'beer', foreach:my.points}">
</ul>
</div>
<div class="con">
<h3>Filtered List</h3>
<ul data-bind="template: {name:'beer', foreach: my.FilteredList}">
</ul>
</div>
<script type="text/html" id="beer">
<li>
<strong data-bind="text: category"></strong>
</br>
<span data-bind="text:name"></span>
<span data-bind="text: lat"></span>
<span data-bind="text: lon"></span>
</li>
</script>
<div id="map"></div>
<div id="eat" data-bind="template: { name: 'pointsTmpl', foreach: my.points }"></div>
<script id="pointsTmpl" type="text/html">
<p>
<span data-bind="text: category"></span>;
<span data-bind="text: lat"></span>;
<span data-bind="text: lon"></span>
</p>
</script>
<!-- list of the imports -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js"></script>
<script src="js/lib/knockout-3.2.0.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script src="js/data.js"></script>
<script src="js/app.js"></script>
<!--
<script src="js/lib/jQuery.js"></script>
<script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<script data-require="knockout@*" data-semver="3.3.0" src="//cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
-->
</body>
$( function() {
my.createMap = function(){
var myOptions = {
zoom: my.sampleData.zoomLevel,
center: new google.maps.LatLng( my.sampleData.centerCoordinates[0], my.sampleData.centerCoordinates[1] ),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// map = new google.maps.Map(document.getElementById('map'), myOptions); // vanilla JS
my.map = new google.maps.Map( $('#map')[0], myOptions); // using jQuery
}
my.mapMarker = function ( category, name, lat, lon) {
this.category = ko.observable(category);
this.name = ko.observable(name);
this.lat = ko.observable(lat);
this.lon = ko.observable(lon);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat, lon),
title: name,
animation: google.maps.Animation.DROP,
map: my.map,
draggable: false
});
// draging for the markers
google.maps.event.addListener(marker, 'drag', function() {
var pos = marker.getPosition();
this.lat(pos.lat());
this.lon(pos.lng());
}.bind(this));
google.maps.event.addListener(marker, 'dragend', function() {
var pos = marker.getPosition();
this.lat(pos.lat());
this.lon(pos.lng());
}.bind(this));
}
my.query = ko.observable("");
my.pusMarkerData = function(item){
// console.log(item);
my.points = ko.observableArray();
for (var j = 0; j < item.length; j++){
my.points.push( new my.mapMarker( item[j]['category'], item[j]['name'], item[j]['lat'], item[j]['lon']));
}
}
my.myDataFilter = function(){
my.FilteredList = ko.pureComputed(function() {
if(my.query() === "") {
return my.points;
}
else {
return ko.utils.arrayFilter(my.points(), function(item) {
return item.name().toLowerCase().indexOf(my.query().toLowerCase())>-1;
});
}
}, this);
}
my.loadMap = function(item){
my.pusMarkerData(item);
}
my.vm = function (){
my.loadMap( my.sampleData.geoCoordinates );
}
var test = new my.vm();
my.createMap();
ko.applyBindings(my.vm);
});
var my = my || { }; //my namespace
my.dataservice = (function (my) {
"use strict";
var getDataSet = function () {
return my.sampleData;
};
return {
getData: getDataSet
};
})(my);
my.sampleData = (function (my) {
"use strict";
var data = {
geoCoordinates : [
{ 'category':'Movie', 'name': "A beautiful mind", 'lat':25.758199, 'lon':-80.373668},
{'category':'Movie', "name": "Fight club",'lat':25.756769, 'lon':-80.369463},
{'category':'TV shows', "name": "House of cards",'lat':25.754064, 'lon':-80.373582}
],
centerCoordinates : [25.754296, -80.377531],
zoomLevel : 16
}
return {
geoCoordinates : data.geoCoordinates,
centerCoordinates: data.centerCoordinates,
zoomLevel: data.zoomLevel
};
})(my);
答案 0 :(得分:1)
你的问题只是一大堆代码。很多都要改变。看看这个:
http://plnkr.co/edit/txUxPhvR9V8xi2pkcRli?p=preview
你想要做的基本事情是:
1)将您的列表绑定到计算属性:像这样:
<div class="content">
<ul data-bind="template: {name:'beer', foreach:my.FilteredList}">
</ul>
</div>
2)将计算属性创建为完整列表的过滤版本:
my.FilteredList = ko.computed(function() {
if (my.query() === "") {
return my.points;
}
else {
return ko.utils.arrayFilter(my.points(), function(item) {
return item.name().toLowerCase().indexOf(my.query().toLowerCase()) > -1;
});
};
3)不要将变量命名为:&#34;啤酒&#34;。