【问题标题】:Button or link to toggle length of multiple lists用于切换多个列表长度的按钮或链接
【发布时间】:2016-10-28 09:36:13
【问题描述】:

我有复选框列表作为过滤器。然而,其中一些列表太长了。我希望能够将它们切换到指定的长度或全长以获得用户体验。 我已经设法让它像这样工作,但问题是使用这种方法,单击链接将切换所有列表,而不仅仅是一个。所以我需要让它分别为每个列表工作。


在我的控制器中:

$scope.limit = 5;
$scope.isShowMore = true;

$scope.showMore = function() {

    $scope.limit = $scope.length;
    $scope.isShowMore = false;
};

$scope.showLess = function() {

    $scope.limit = 5;
    $scope.isShowMore = true;
}

在我看来:

<ul>
 <h4>By Country</h4>
 <li ng-repeat="country in countries | limitTo:limit">
  <div class="form-check">
   <label class="form-check-label">
    <input style="vertical-align:middle;position:relative;bottom:3px;" ng-model="filter.country[country]" class="form-check-input" type="checkbox" checked="checked" value="{{country}}">{{country | capitalise}}
   </label>
  </div>
 </li>
</ul>
<a href="javascript:;" ng-click="showMore()" ng-show="isShowMore">... Show More</a><a href="javascript:;" ng-click="showLess()" ng-hide="isShowMore">... Show Less </a>

我在想我应该把它从我的控制器中移出一个指令,但不知道这是否正确或如何这样做。我是AngularJS的新手,请帮忙! :)

【问题讨论】:

    标签: javascript jquery angularjs list toggle


    【解决方案1】:

    是的,最好有一个我已经制定的自定义指令,如果将来如果您想使用多个复选框并需要收集所有收集的项目,您可以使用如下所示的自定义指令。这里有一个link 说明如何使用它。

    以下是 HTML 中的示例代码 sn-p

    <body ng-app="mainApp" ng-controller="MainCtrl">
     <h1>Multi Check box</h1>
     <multi-checkbox selectedlist="req.selectedList" orginallist="req.sourceList" value="code" label="desc" all="true" sort-by="desc"></multi-checkbox>
     <pre ng-cloak>{{req.selectedList |json}}</pre>
    </body>
    

    这需要一个源列表(orginallist)和一个目标列表(selectedlist),选择的值应该放在哪里,它还会根据您的需要对列表进行排序。

    只需在你的 JS 文件中添加这个指令,你就可以随时随地使用这个指令,这是一个一次性的活动。所以我希望这对你有帮助。

    mainApp.directive('multiCheckbox', ['$log', '$filter', '$timeout', function($log, $filter, $timeout) {
    
        return {
    
            restrict: 'EA',//E-element & A - attribute
    
            template:
    
                '<div> <div ng-show="checkbox.showAll" class="checkbox"> ' +
    
                '<label style="font-size: 12px"> <input type="checkbox" ' +
    
                'id="all" name="all" ng-model="checkbox.all" ' +
    
                'ng-checked="checkbox.all" ng-change="selectAll()" /> All ' +
    
                '</label> ' +
    
                '</div>' +
    
                '<div ng-repeat="item in list  track by $index "class="checkbox"> ' +
    
                '<label style="font-size: 12px"> <input type="checkbox" ' +
    
                'id="{{item.value}}" name="{{item.label}}"  ' +
    
                'ng-checked="item.checked" ng-click="$parent.toggle($index)"/> {{item.label}}' +
    
                '</label>' +
    
                '</div> </div>',
    
            replace: true,  //to replace our custom template in place of tag <multi-checkbox>
    
            transclude: false,//make it true if we want to insert anything  btw directive tags
    
            scope: {  //isolate scope created 
    
                selectedlist: '=',
    
                orginallist: '=',
    
                value: '@',
    
                label: '@',
    
                all: '@',
    
                sortBy: '@'
    
            },
    
            link: function($scope, element, attrs) {
    
                $scope.checkbox = {};
    
                $scope.checkbox.all = false; //set 'All' checkbox to false
    
                $scope.checkbox.showAll = $scope.all == 'true' ? true : false;//to show/hide 'All' checkbox
    
                //function called on click of check box
                $scope.toggle = function(index) {
    
                    var item = $scope.list[index];
    
                    var i = $scope.selectedlist.length > 0 ? $scope.selectedlist.indexOf(item.value) : -1;
    
                    item.checked = !item.checked;
    
                    if (!item.checked) {
    
                        $scope.selectedlist.splice(i, 1);//remove item if unchecked
    
                        $scope.checkbox.all = false;//make 'All' to uncheck too
    
                    } else if (item.checked) {
    
                        $scope.selectedlist.push(item.value);//add item if checked
    
                    }
    
                };
    
                //function called when 'All' checkbox is checked
                $scope.selectAll = function() {
    
                    var totalList = $scope.list;
    
                    $scope.selectedlist = [];
    
                    //if selected add all items 
                    //if unchecked remove all items from selected list
                    angular.forEach(totalList, function(item) {
    
                        item.checked = $scope.checkbox.all;
    
                        if (item.checked) {
    
                            $scope.selectedlist.push(item.value);
    
                        } else {
    
                            $scope.selectedlist = [];
    
                        }
    
                    });
    
                };
    
    
                //always watch my source list if it has been modified and update back..
                $scope.$watch('orginallist', function(value) {
    
                    //sort accordingly..
                    value = $filter('orderBy')(value, $scope.sortBy);
    
                    $scope.list = [];
    
                    if (angular.isArray(value)) {
    
                        angular.forEach(value, function(item) {
    
                            $scope.list.push({
    
                                value: item[$scope.value],
    
                                label: item[$scope.label],
    
                                checked: item.checked
    
                            });
    
                        });
    
                    }
    
                }, true);
    
    
                //clear 'All' checkbox value if all items are de selected
                $scope.$watch('selectedlist', function(value) {
    
                    if (!angular.isArray(value) || (angular.isArray(value) && value.length <= 0)) {
    
                        $scope.checkbox.all = false;
    
                    }
    
                }, true);
            }
    
        };
    
    }]);
    

    【讨论】:

    • 抱歉回复晚了,有时很难找到空闲时间......这非常有效。非常感谢您的帮助!
    【解决方案2】:

    您可以创建一个指令,该指令将在ul 元素之后添加show moreshow less 链接,并根据您传递给指令的值进行初始化。看看这个JSFiddle

    指令:

    MyApp.directive("showMoreLess", function() {
      return {
        restrict: "A",
        replace: false,
        transclude: true,
        scope: {
          min: "@minValue",
          max: "=maxValue"
        },
        template: '<ng-transclude></ng-transclude><a href="" ng-click="showMore()" ng-show="!isShowMore">... Show More</a><a href="javascript:;" ng-click="showLess()" ng-show="isShowMore">... Show Less </a>',
        link: function(scope, ele, attr) {
          scope.limit = parseInt(scope.min);
        },
        controller: function($scope) {
          $scope.showMore = function() {
            $scope.limit = parseInt($scope.max);
            $scope.isShowMore = true;
          };
          $scope.showLess = function() {
            $scope.limit = parseInt($scope.min);
            $scope.isShowMore = false;
          }
        }
      };
    });
    

    模板:

    <ul show-more-less min-value="3" max-value="countries.length">
       <h4>By Country</h4>
       <li ng-repeat="country in countries | limitTo:$parent.limit"><!-- Note that we are using $parent.limit since transclude child elements don't have access to transclude element scope -->
        ...
       </li>
    <ul>
    
    • 最小值:此数字的初始限制列表
    • 最大值:要显示的列表项的最大数量

    注意:我们在过滤器中使用$parent.limit,因为transclude 子元素无权访问transclude 元素范围。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-24
      • 1970-01-01
      • 2015-02-06
      • 1970-01-01
      • 2012-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多