AngularJS下拉多选框异常:数据不显示及加载指示器失效
解决AngularJS下拉多选框的加载与显示问题
我看了你的代码,发现几个关键问题导致下拉框无内容、加载指示器异常,咱们一个个来修复:
核心问题分析与修复步骤
1. 初始数据未同步到data2Show
你初始化了$scope.data来存加载的数据,但下拉列表绑定的data2Show一开始是空的,只有修改搜索框时才会调用filter()赋值。所以页面加载后下拉框没内容,得在初始数据加载完成后手动调用一次filter(),把初始数据同步过去。
2. 加载指示器逻辑错误
- 调用
loadMore()时,你没有先把$scope.dataLoading设为true,导致加载状态不会显示; - 初始请求的
finally里直接把dataLoading设为false没问题,但loadMore要先开启加载状态再发请求。
3. loadMore的数组越界问题
当counter + chunks超过数据总长度时,循环会尝试访问不存在的数组元素,导致报错。得判断当前索引是否在数组范围内再添加。
4. HTML中loadMore的点击事件未完成
你的HTML代码最后ng-click="后面没写完,直接截断了,这会导致点击“加载更多”完全没反应。
5. isChecked函数未定义
模板里用了ng-checked="isChecked(data)",但控制器里没实现这个函数,会抛出错误。其实直接用data.flag就可以了,因为你已经把复选框的ng-model绑定到data.flag了。
修正后的完整代码
控制器代码(JS)
"use strict"; var app = angular.module("myApp", []); app.controller("myCtrl", function ($scope, $http) { /* ===== VARIABLES ===== */ /* loading indicator */ $scope.dataLoading = true; // data variables $scope.data2Show = []; $scope.data = []; // variables for get requests var counter = 0; var chunks = 5; // variables for checkbox $scope.selectedItems = []; //variables for opening dropdown $scope.selectEnable = false; // method for opening dropdown $scope.openSelect = function () { $scope.selectEnable = !$scope.selectEnable; }; /* ===== Functions ===== */ // initial success method function onSuccess(response) { // 循环时判断索引是否在数组范围内 for (let i = 0; i < chunks && i < response.data.length; i++) { $scope.data.push(response.data[i]); } counter += chunks; // 初始数据加载完成后同步到data2Show $scope.filter(); } // Error method function onError(response) { console.log("error", response); } // load more success method function loadMoreSuccess(response) { // 防止数组越界 for (let i = counter; i < (counter + chunks) && i < response.data.length; i++) { $scope.data.push(response.data[i]); } counter += chunks; // 加载更多后更新显示列表 $scope.filter(); } /* get methods */ // initial get method $http({ method: "GET", url: "data.json" }) .then(onSuccess) .catch(onError) .finally(function () { $scope.dataLoading = false; }); // load more method $scope.loadMore = function () { // 先开启加载状态 $scope.dataLoading = true; $http({ method: "GET", url: "data.json" }) .then(loadMoreSuccess) .catch(onError) .finally(function () { $scope.dataLoading = false; }); }; /* 复选框状态变更处理 */ $scope.itemChecked = function (data) { var selected = $scope.selectedItems.indexOf(data.item); if (selected == -1) { $scope.selectedItems.push(data.item); } else { $scope.selectedItems.splice(selected, 1); } }; // 搜索过滤函数 $scope.filter = function () { if (!$scope.searchField) { $scope.data2Show = angular.copy($scope.data); /* 搜索框为空时显示全部已加载数据 */ } else { /* 搜索框不为空时过滤匹配项 */ $scope.data2Show = []; $scope.data.map(function (itm) { // 加入大小写不敏感匹配 if (itm.item.toLowerCase().indexOf($scope.searchField.toLowerCase()) != -1) { $scope.data2Show.push(itm); } }); } }; });
CSS代码
ul li { list-style: none; text-align: center; } ul { height: 100px; overflow-y: scroll; padding-left: 0; } #loadMore { text-align: center; color: #aaa; background: #ddd; cursor: pointer; padding: 5px; } #category { text-align: center; background: #ddd; } #listContainer { width: 20%; } span { cursor: pointer; } #selectContainer { margin-top: 5px; }
HTML代码
<!DOCTYPE html> <html lang="en" ng-app="myApp"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script> <link rel="stylesheet" href="stylesheet/style.css"> </head> <body ng-controller="myCtrl"> <input type="text" ng-click="openSelect()" placeholder="点击打开下拉框"> <div id="selectContainer" ng-show="selectEnable"> <div>已选:{{selectedItems.toString() || '无'}}</div> <input type="text" id="searchField" ng-model="searchField" ng-change="filter()" placeholder="搜索"> <div id="listContainer"> <ul id="innerContainer"> <li ng-repeat="data in data2Show"> <input type="checkbox" ng-change="itemChecked(data)" name="select" ng-model="data.flag"> {{data.item}} </li> </ul> <div ng-show="dataLoading" style="text-align:center;">loading...</div> <li id="loadMore" ng-click="loadMore()" ng-hide="counter >= data.length">加载更多</li> </div> </div> </body> </html>
额外优化点
- 在
filter()里加入了大小写不敏感的搜索,提升用户体验; - 添加了
ng-hide="counter >= data.length",当数据全部加载完成后隐藏“加载更多”按钮; - 给输入框添加了占位提示,优化视觉体验;
- 修复了ul的默认padding,避免列表缩进问题。
内容的提问来源于stack exchange,提问作者mssoheil
相关产品推荐
相关产品推荐

