简体   繁体   中英

Angular - Filtering data based on bootstrap dropdown selection

I'm trying to filter a list based on a selection from a bootstrap dropdown, but cannot seem to get it to work. Here's my code:

<body>
  <div class="toolbar-wrapper" >
    <div class="btn-group container" role="group" ng-controller="filterController">
      <div class="dropdown">
        <button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
          {{filter}}
          <span class="caret"></span>
        </button>
        <ul class="dropdown-menu">
          <li ng-repeat="severity in severityLevels"><a href="#" ng-click="changeSeverity(severity)">{{severity}}</a></li>
        </ul>
      </div>
    </div>
  </div>
  <div class="logMessages" ng-controller="logController">
    <div >
    <ul>
      <li class="message" ng-repeat="logData in data | filter: filter  | limitTo: quantity">
        {{logData.timestamp}} : {{logData.severity}} : {{logData.message}}
      </li>
    </ul>
  </div>
  </div>
</body>

Javascript:

var app = angular.module('UnifyLog', []);

app.controller('filterController', function($scope) {
  $scope.severityLevels = [
    'ERROR',
    'WARN',
    'INFO',
    'DEBUG'
  ];

  $scope.filter = '';

  $scope.resetFilter = function() {
    $scope.filter = '';
  };

  $scope.changeSeverity = function(severity) {
    $scope.filter = severity;
  }

})
.controller('logController', function ($scope, $http) {

  $http.get("https://clock/settings/get_log_messages", {}).then(
      function (response) {
        $scope.data = response.data;
      },
      function (response) {
        console.log("fail:" + response);
      }
  );

  $scope.quantity=100
});

I know you can use ng-model data binding with a select directive, but I want to use a bootstrap dropdown.

The code above is updating the scope.filter variable but the list of log messages does not filter.

The http request is getting back a json array with log data objects containing message, timestamp, and severity fields.

Try calling $scope.apply() :

$scope.changeSeverity = function(severity) {
    $scope.filter = severity;
    $scope.apply()
}

Look here for more information, and consider another approach (use real data-binding instead of a custom callback): https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply()

I would create a customer severity filter like so:

.filter('severityFilter', function () {
    return function (input, severity) {
        var out = [];
        if (input && input != []) {
            angular.forEach(input, function (thing) {
               if(thing.severity === severity){
                   out.push(thing);
               }
            });
        }
        return out;
    }
})

Then apply it like this:

ng-repeat="logData in data | severityFilter: severity | limitTo: quantity">

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM