You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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>

额外优化点

  1. 在filter()里加入了大小写不敏感的搜索,提升用户体验;
  2. 添加了ng-hide="counter >= data.length",当数据全部加载完成后隐藏“加载更多”按钮;
  3. 给输入框添加了占位提示,优化视觉体验;
  4. 修复了ul的默认padding,避免列表缩进问题。

内容的提问来源于stack exchange,提问作者mssoheil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:54:08