Knockout

时间:2015-04-23 20:52:26

标签: javascript knockout.js

我正在研究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']));
        } 
    }

我的问题是 -

  1. 如何在my.FilteredList显示过滤后的标记后调用my.loadMap(testValues)?
  2. 使用搜索栏的过滤功能并不是我想要实现的功能。以下是jsFiddle中的内容示例:http://jsfiddle.net/mythical/XJEzc/
  3. 由于

    的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);
    

1 个答案:

答案 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;。