【问题标题】:Filter ng-repeat based on user selection根据用户选择过滤 ng-repeat
【发布时间】:2015-06-26 20:04:12
【问题描述】:

我目前正在制作音乐目录,并尝试实现允许用户从 艺术家流派

列表中过滤目录的功能

名单:

    <ul class="artists">
        <li class="title">
            <h5>Artists</h5>
            <ul class="sub-menu">
                <li ng-repeat="artist in music | orderBy:'-views'">
                    <p ng-click="select(artist.artist)">{{artist.artist}}</p>
                </li>
            </ul>
        </li>
    </ul>

我试图构建一个自定义过滤器,但无法完全掌握这个概念,我设法做的是从所选选择中获取值

    // value from ng-click
    $scope.select = function(value){
        filterBy = value;
    }

我知道我可以添加过滤器:通过添加 ng-repeat

ng-repeat="artist in music | filter: {artist:'artistName' | orderBy:'-views'"}

但是我如何将 artist: 'value' 更改为从列表中选择的内容

这是我要过滤的主要区域

    <div class="item" ng-repeat="artist in music | orderBy:'-views'"> 
        <div class="img">
            <img ng-src="{{artist.image}}"/>
        </div>
        <div class="info">
            <h6>{{artist.artist}}</h6>
            <p>{{artist.songName}}</p>
        </div>
    </div>

当视图加载时,所有项目都应该显示,然后如果用户愿意,可以从列表中选择艺术家或流派以过滤到该结果。我的想法是可能将自定义过滤器函数放在点击函数中,因此当用户从列表中选择时,点击函数中的值可以解析到自定义过滤器并使用正确的值更新过滤器。但是,我无法实现。

我对 angular.js 很陌生,所以如果我没有完全正确地解释它,这里是一个 JSfiddle 复制我的项目。

http://jsfiddle.net/0n2qptg6/5/

提前感谢您的任何帮助、建议和批评

【问题讨论】:

    标签: javascript angularjs dynamic web-applications filtering


    【解决方案1】:

    首先过滤器参数是可绑定的。这意味着你可以做这样的事情。

    ng-repeat="artist in music | filter: {artist: path.to.artistSerachTerm | orderBy:'-views'"}.

    这是一个使用文本输入和选择列表作为过滤器的示例。但是您可以将这个想法扩展为复选框列表以及选择下拉列表。

    var app = angular.module('main', []);
    
    app.filter('unique', function() {
    
      return function (arr, field) {
        var o = {}, i, l = arr.length, r = [];
        for(i=0; i<l;i+=1) {
          o[arr[i][field]] = arr[i];
        }
        for(i in o) {
          r.push(o[i]);
        }
        return r;
      };
    
    });
    
    app.controller('MainCtrl', function($scope, $http, $filter) {
    
        $scope.music = [ { "artist": "noisia", "songName": "machine gun", "genre": "Drum and Bass", "views": "19" }, { "artist": "etnik", "songName": "n7", "genre": "Techno", "views": "30" }, { "artist": "Jack U", "songName": "To U", "genre": "RnB", "image": "images/cover_3.jpg", "views": "32" }, { "artist": "Makonnen", "songName": "Tuesday", "genre": "Electronic", "image": "images/cover_4.jpg", "views": "72" }, { "artist": "Dillon Francis", "songName": "When We Were Young", "image": "images/cover_5.jpg", "views": "54" }, { "artist": "Justice", "songName": "Stress", "image": "images/cover_6.jpg", "views": "93" } ];
        
        $scope.filteredBy = {
            artist: '',
            genre: ''
        };
    
        $scope.clear = function() {
            $scope.filteredBy.artist = '';
            $scope.filteredBy.genre = '';
        }
    });
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet"/>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.min.js"></script>
    <div  ng-app="main"  ng-controller="MainCtrl">
        <div class="nav">
            <p> 
                <label for="byArtistInput">Choose Artist:</label>
                <input id="byArtistInput" type="text" ng-model="filteredBy.artist" />
              
                <label for="byGenreInput">Choose genre:</label>
                <select id="byGenreInput" 
                        ng-model="filteredBy.genre" 
                        ng-options="song.genre as song.genre for song in music | unique: 'genre'"></select>
                <button type="button" ng-click="clear()">clear</button>
            </p>
        </div>
    
        <div class="clear"></div>
    
        <div class="content">
            <div class="item" ng-repeat="artist in music | filter:filteredBy | orderBy:'-views'">
                <div class="border">
                    <!--   | filter: {artist:'etnik'}   -->
                    <div class="img"></div>
                    <div class="sub-info">
                       <h4>{{artist.artist}}</h4>   
                       <p>{{artist.songName}}</p>  
                    </div>
                </div>
            </div>
        </div>
    </div>

    【讨论】:

      【解决方案2】:

      Demo

      您需要将过滤器分配给 $scope,以便它可以用作您的音乐专辑列表的过滤器:

      $scope.selectArtist = function(value){
          //pass from ng-click
          $scope.filterByArtist = value;
          alert(filterBy);
      }
      
      $scope.selectGenre = function(value){
          //pass from ng-click
          $scope.filterByGenre = value;
          alert(filterBy);
      }
      

      然后,将过滤器应用到您的音乐专辑列表:

      <div class="item" ng-repeat="artist in music | 
         filter:{ artist: filterByArtist, genre: filterByGenre } |
         orderBy:'-views'">
      

      【讨论】:

      • 太棒了!谢谢,我试图在过滤器的 selectArtist 函数中创建另一个函数,而不是直接分配它。如果您有时间回答,我还有另一个问题,我更新了小提琴-jsfiddle.net/z1r930L6/4-我现在拥有的一件事是,当我将流派重复到列表中时,我不确定如何去停止重复相同的流派。例如,在更新的小提琴中,您会看到“电子”类型是 3 首歌曲的类型,因此它重复了 3 次,我只想将其限制为 1。
      • 您可以使用自定义的“独特”过滤器检查我的答案
      【解决方案3】:

      一种选择是拥有一个过滤器对象并在您单击不同的元素时对其进行更新。当然在 ng-repeat 标签中使用过滤器。

      <div class="item" ng-repeat="artist in music | filter:filteredBy | orderBy:'-views'">
      

      也将方法更改为以下

      $scope.selectArtist = function(value){
         //pass from ng-click
          $scope.filteredBy.artist = value;
      }
      
      $scope.selectGenre = function(value){
          //pass from ng-click
          $scope.filteredBy.genre = value;
      }
      

      查看更新的小提琴示例

      http://jsfiddle.net/0n2qptg6/6/

      当然,如果你愿意,你可以尝试对其进行一些优化,但这应该可以工作

      【讨论】:

        猜你喜欢
        • 2015-01-09
        • 2017-10-14
        • 1970-01-01
        • 1970-01-01
        • 2017-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-25
        相关资源
        最近更新 更多