简体   繁体   English

AngularJS orderBy-按对象的字符串属性排序吗?

[英]AngularJS orderBy - Sort by string property of an object?

I'm trying to sort items in a list of tasks by both their added date and their listed priority. 我正在尝试按任务的添加日期和列出的优先级对任务列表中的项目进行排序。 I've done the sorting by date, but how can I sort the items so that those with the 'HIGH' property are organised first in the list? 我已经按日期进行了排序,但是如何对项目进行排序,以使具有“ HIGH”属性的项目在列表中排在首位?

EDIT: I need it to sort by HIGH when this option is select from the 'Sort By' select box above the task list. 编辑:当从任务列表上方的“排序依据”选择框中选择此选项时,我需要按高排序。

Codepen: http://codepen.io/anon/pen/ryyQzy . Codepen: http ://codepen.io/anon/pen/ryyQzy。

HTML: HTML:

<md-list class="md-padding">

                   <div layout="row">

                        <md-input-container class="md-block" flex="70">

                            <input type="text" ng-model="search" name="search" placeholder="Search by Task Name"></input>  

                        </md-input-container>

                        <md-input-container flex="30">

                            <md-select name="priority" ng-model="task.priority" placeholder="Sort By">

                                <md-option value="Low">Newest First</md-option>

                                <md-option value="HIGH">High Priority First</md-option>

                            </md-select>

                        </md-input-container>

                    </div>

                    <md-subheader class="md-no-sticky">Current Tasks ({{taskList.length}})</md-subheader> 

                    <md-list-item class="md-3-line" ng-repeat="task in taskList | orderBy:sortByNewest | filter:search">

                       <div class="md-list-item-text" layout="column">

                            <p>{{task.name}}</p>

                            <p>Priority: {{task.priority}}</p>

                            <span class="weak">Added {{task.addedOn | date: 'medium'}}</span>

                        </div>

                        <md-checkbox class="md-secondary" ng-model="task.completed"></md-checkbox>

                        <md-divider ng-if="!$last"></md-divider>

                    </md-list-item>

                </md-list>

JS: JS:

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

function menuController ($scope, $mdDialog) {
    var originatorEv;
    this.openMenu = function($mdOpenMenu, ev) {
        originatorEv = ev;
        $mdOpenMenu(ev);
    };
};  

app.controller('todoController', function($scope, $mdDialog, $mdToast, $filter) {

    $scope.sortByNewest = '-addedOn';
    //$scope.sortByPriority = ' ';

    $scope.taskList = [
        { name: 'Task 1', priority: 'Low', completed: false, addedOn: 1488722128000 },
        { name: 'Task 2', priority: 'HIGH', completed: false, addedOn: 1488722128000 },
    ];

    $scope.addTask = function() {
        if (angular.isUndefined($scope.taskName) || $scope.taskName.length === 0) {
            var alert =  $mdDialog.alert()
                .parent(angular.element(document.querySelector('#popupContainer')))
                .clickOutsideToClose(true)
                .title('Error')
                .textContent('You must enter a task name and select a priority level')
                .ok('Close');
            $mdDialog.show( alert )
                .finally(function() {
                    alert = undefined;
                });
        }
        else {
            $scope.taskList.push({name: $scope.taskName, priority: $scope.task.priority, addedOn: Date.now()});
            $scope.taskName = "";
            $scope.task.priority = "";
            var pinTo = $scope.getToastPosition();
            $mdToast.show (
                $mdToast.simple()
                .textContent('Task Added')
                .position(pinTo)
                .hideDelay(3000)
            )
        }
    };

    $scope.selectAll = function() {
        angular.forEach($scope.taskList, function(task) {
            task.completed = true;
        });  
    };

    $scope.selectNone = function() {
        angular.forEach($scope.taskList, function(task) {
            task.completed = false;
        });  
    };

    $scope.delete = function(ev) {

        var completedTasks = $filter('filter')($scope.taskList, { completed: true}, true);

        if (completedTasks.length > 0) {
            console.log('show dialog box to confirm');   
            var confirm = $mdDialog.confirm()
                .title ('Are you sure you want to delete the selected tasks?')
                .textContent ('Deleted tasks can\'t be recovered.')
                .targetEvent (ev)
                .ok ('Confirm')
                .cancel ('Cancel')
            clickOutsideToClose: false;
            $mdDialog.show(confirm).then(function() {
                if (completedTasks.length > 1) {
                    var pinTo = $scope.getToastPosition();
                    $mdToast.show (
                        $mdToast.simple()
                        .textContent('Tasks Deleted')
                        .position(pinTo)
                        .hideDelay(3000)
                    )
                }
                else {
                    var pinTo = $scope.getToastPosition();
                    $mdToast.show (
                        $mdToast.simple()
                        .textContent('Task Deleted')
                        .position(pinTo)
                        .hideDelay(3000)
                    )
                }
                $scope.status = 'Tasks Deleted';
                var i = $scope.taskList.length;
                while (i--) {
                    var task = $scope.taskList[i];
                    if(task.completed) {
                        $scope.taskList.splice(i, 1);
                    }
                }

            }, 
            function() {
                $scope.status = 'Deletion Cancelled';
            });
        } 

        else {
            $mdDialog.show(
                $mdDialog.alert()
                    .parent(angular.element(document.querySelector('#popupContainer')))
                    .clickOutsideToClose(true)
                    .title('Error')
                    .textContent('You must select at least one task to delete.')
                    .ok('Close')
                    .targetEvent(ev)
            );
        }
    };

    function DialogController($scope, $mdDialog) {
        $scope.hide = function() {
            $mdDialog.hide();
        };

        $scope.cancel = function() {
            $mdDialog.cancel();
        };

        $scope.answer = function(answer) {
            $mdDialog.hide(answer);
        };
    };

    var last = {
        bottom: false,
        top: true,
        left: false,
        right: true
    };

    $scope.toastPosition = angular.extend({},last);

    $scope.getToastPosition = function() {
        sanitizePosition();
        return Object.keys($scope.toastPosition)
        .filter(function(pos) { return $scope.toastPosition[pos]; })
        .join(' ');
    };

    function sanitizePosition() {
        var current = $scope.toastPosition;
        if ( current.bottom && last.top ) current.top = false;
        if ( current.top && last.bottom ) current.bottom = false;
        if ( current.right && last.left ) current.left = false;
        if ( current.left && last.right ) current.right = false;
        last = angular.extend({},current);
    };

});

app.controller('toastController', function($scope, $mdToast) {
    $scope.closeToast = function() {
        $mdToast.hide();
    }

});

You need to use ng-model="search.name" and ng-model="search.priority" . 您需要使用ng-model="search.name" and ng-model="search.priority" then it will read all search criteria from search object.( filter:search ) 然后它将从search对象中读取所有搜索条件。( filter:search

Check out updated Codepen 查看更新的Codepen

Please update your view as shown below: Search by Task Name model as ng-model="search.name" instead of ng-model="search" Sort By model as ng-model="search.priority" instead of ng-model="sortBy" 如下图所示,请更新您的观点:通过任务名称模型搜索ng-model="search.name" ,而不是ng-model="search"排序模型作为ng-model="search.priority" ,而不是ng-model="sortBy"

<div layout="row">

  <md-input-container class="md-block" flex="70">

    <input type="text" ng-model="search.name" name="search" placeholder="Search by Task Name"></input>

  </md-input-container>

  <md-input-container flex="30">

    <md-select name="priority" ng-model="search.priority" placeholder="Sort By">

      <md-option value="Low">Newest First</md-option>

      <md-option value="HIGH">High Priority First</md-option>

    </md-select>

  </md-input-container>

</div>

orderBy needs the property names of the objects it is supposed to sort. orderBy需要它应该排序的对象的属性名称。 So the option s inside your select should define these property names like this: 因此,您selectoption s应该定义这些属性名称,如下所示:

<md-select name="sortBy" placeholder="Sort By" ng-model="sortBy">
  <md-option value="addedOn">Newest First</md-option>
  <md-option value="priority">High Priority First</md-option>
</md-select>

If orderBy encounters a string inside these properties it will sort the array alphabetically. 如果orderBy在这些属性内遇到一个字符串,它将按字母顺序对数组进行排序。 So this already conveniently works for you since H igh comes before L ow. 因此,这已经方便地为你工作因为h室内运动场配备大号流之前。

From the Angular Documentation: 从Angular文档中:

The default, built-in comparator should be sufficient for most usecases. 对于大多数用例,默认的内置比较器应该足够。 In short, it compares numbers numerically, strings alphabetically (and case-insensitively), for objects falls back to using their index in the original collection, and sorts values of different types by type. 简而言之,它以数字方式(按字母顺序(不区分大小写))比较数字,以使对象不使用原始集合中的索引,并按类型对不同类型的值进行排序。

https://docs.angularjs.org/api/ng/filter/orderBy https://docs.angularjs.org/api/ng/filter/orderBy

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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