【发布时间】:2015-07-02 06:24:22
【问题描述】:
我正在开发一个 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']));
}
}
我的问题是 -
- 在获取 my.FilteredList 后如何调用 my.loadMap(testValues) 以显示过滤后的标记?
- 使用搜索栏的过滤功能并不是我想要实现的。以下是 jsFiddle 中意图的示例:http://jsfiddle.net/mythical/XJEzc/
谢谢
index.html
<!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>
app.js
$( 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);
});
data.js
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);
【问题讨论】:
-
你在问什么?有什么不工作吗?
-
aquinas @我想在应用程序的右上角提供一个使用名称(my.sampleData.geoCoordinates.name)的搜索功能。因此,当您开始在搜索栏中输入姓名的前几个字母时,列表中的其他选项将被过滤掉。
-
我现在更新了问题。