AngularJS升级ui-select后下拉框始终向后端传'true'问题排查
问题描述
我在开发AngularJS项目时,将组件库从ui-select2升级为ui-select,原ui-select2代码如下:
<select data-ui-select2="{allowClear: true}" ui-select2="clearDropDown" ng-model="isFinalSubmission" data-placeholder="Final Submission Done?" class="padding-left-right-zero"> <option></option> <option value="true">Yes</option> <option value="false">No</option> </select>
升级后的ui-select代码:
<ui-select style="cursor: pointer;" ng-model="isFinalSubmission" theme="select2" class="padding-left-right-zero" search-enabled="true" ng-init="options = [{ value: 'true', label: 'Yes' },{ value: 'false' , label: 'No' }]"> <ui-select-match allow-clear="true" placeholder="Final Submission Done?">{{$select.selected.label}}</ui-select-match> <ui-select-choices repeat="option.value as option in options | filter: $select.search"> {{option.label}} </ui-select-choices> </ui-select> <div class="col-sm-5"> <br /> <button type="button" class="btn btn-sm btn-primary pull-right" style="border-radius:5px" ng-click="loadGrid()">Search</button> </div>
当前问题:下拉框选择值能正常显示,但执行操作时,发送到后端的始终是初始固定值true,选择“No”时后端仍收到true。
对应的控制器核心代码片段:
(function (window, angular, undefined) { 'use strict'; angular.module('angularModule.controllers').controller('searchHoldingCtrl', ['$scope', '$compile', '$window', 'ajaxCall', '$controller', 'checkPermissions', '$rootScope', '$location', 'permissionCheckService', 'fileDownloadService', 'holdingColumns','$timeout', function ($scope, $compile, $window, ajaxCall, $controller, checkPermissions, $rootScope, $location, permissionCheckService, fileDownloadService, holdingColumns, $timeout) { permissionCheckService.check('ETT_Reports_View'); $controller('commonCtrl', { $scope: $scope }); $scope.selectIsinList(); $scope.searchIsin = { Id: null }; $scope.selectOptionsEmployeePromise(); $scope.searchEmployee = { Id: null }; $scope.searchTimePeriod = {} $scope.searchClass = {} $scope.searchParentCompany = {}; $scope.copyHoldingToOpening = {}; $scope.searchTimePeriodType = {}; $scope.isFinalSubmission = true; // 初始布尔值 $scope.isTimePeriodShow = false; $scope.isHoldingdateShow = false; $scope.loadGrid(); $scope.loadGrid = function (reset) { $scope.reset = reset ? true : false; $scope.isGridIsShown = true; $scope.gridconfig.isLocalData = false; $timeout(function () { $scope.$broadcast('LoadKendoGridEvent') }) }; $scope.ExportAnnualHoldingPDFReport = function () { var url = "/ETT/Reports/ExportAnnualHoldingPDFReport"; var emp = isValidObject($scope.searchEmployee) ? $scope.searchEmployee.Id : null; var time = isValidObject($scope.searchTimePeriod) ? $scope.searchTimePeriod.Id : null; var holdingDate = isValidObject($scope.model.searchHoldingDate) ? $scope.model.searchHoldingDate : ""; var timePeriodTypeId = isValidObject($scope.searchTimePeriodType) ? $scope.searchTimePeriodType.Id : null; var isin = isValidObject($scope.searchIsin) ? $scope.searchIsin.Id : null; var classId = isValidObject($scope.searchClass) ? $scope.searchClass.Id : null; var parentCompanyId = isValidObject($scope.searchParentCompany) ? $scope.searchParentCompany.Id : null; var isFinalSubmission = isValidObject($scope.isFinalSubmission) ? $scope.isFinalSubmission : null; $rootScope.viewLoading = true; fileDownloadService.downloadFilePost(url, JSON.stringify({ emp: emp, timePeriod: time, holdingDate: holdingDate, timePeriodTypeId: timePeriodTypeId, isin: isin, classId: classId, parentCompanyId: parentCompanyId, isFinalSubmission: isFinalSubmission })).then(function (data) { if (!angular.isUndefined(data) && data.IsError == true) { alertify.error(data.Message); $rootScope.viewLoading = false; return; } else { $rootScope.viewLoading = false; } }); } //Search $scope.gridconfig.getData = function (e) { $scope.gridconfig.isLocalData = true; $scope.model.RowsPerPage = $scope.reset ? 20 : e.data.pageSize; $scope.model.PageNumber = $scope.reset ? 1 : e.data.page; var emp = $scope.searchEmployee == undefined ? null : $scope.searchEmployee.Id; var time = $scope.searchTimePeriod == undefined ? null : $scope.searchTimePeriod.Id; var holdingDate = $scope.model.searchHoldingDate == undefined ? "" : $scope.model.searchHoldingDate; var timePeriodTypeId = $scope.searchTimePeriodType == undefined ? null : $scope.searchTimePeriodType.Id; var isin = $scope.searchIsin == undefined ? null : $scope.searchIsin.Id; var classId = $scope.searchClass == undefined ? null : $scope.searchClass.Id; var parentCompanyId = $scope.searchParentCompany == undefined ? null : $scope.searchParentCompany.Id; var isFinalSubmission = $scope.isFinalSubmission == undefined ? null : $scope.isFinalSubmission; $rootScope.viewLoading = true; ajaxCall.get('/ETT/Reports/SearchHoldings?emp=' + emp + '&timePeriod=' + time + '&holdingDate=' + holdingDate + '&timePeriodTypeId=' + timePeriodTypeId + '&isin=' + isin + '&classId=' + classId + '&parentCompanyId=' + parentCompanyId + '&isFinalSubmission=' + isFinalSubmission).then(function (data) { if (angular.isUndefined(data) && data == null) { $scope.holdingDataSource = []; return; } if (!data.IsError) { $scope.holdingDataSource = data.SearchResults; $scope.gridconfig.ds = getRecordsForPage($scope.holdingDataSource, $scope.model.PageNumber, $scope.model.RowsPerPage); $scope.gridconfig.dataCount = $scope.holdingDataSource.length; e.success({ data: $scope.gridconfig.ds, total: $scope.gridconfig.dataCount }); $rootScope.viewLoading = false; } else { alertify.error(data.Message) $rootScope.viewLoading = false; } }); }; }]); })(window, window.angular);
已尝试操作:
- 查阅ui-select文档确认配置正确
- 验证
isFinalSubmission是否包含预期数据
预期行为:下拉框正确反映选中选项,向后端发送对应值。
问题原因与解决方案
核心原因
ui-select中repeat="option.value as option in options"会将选中的option.value(字符串类型的'true'/'false')绑定到ng-model,但控制器中初始值$scope.isFinalSubmission = true是布尔类型。AngularJS的模型绑定会因为类型不匹配导致更新失败,视图显示正常但实际模型值未被修改。
解决步骤
方案1:统一为字符串类型(适配现有选项配置)
- 修改控制器初始值为字符串类型,和ui-select选项的value一致:
$scope.isFinalSubmission = 'true'; // 替换原来的布尔值true - 检查
isValidObject函数逻辑,确保它能正确识别字符串类型的'true'/'false',避免在请求中被错误替换为null。
方案2:统一为布尔类型(适配后端接收需求)
如果后端期望接收布尔类型参数,调整如下:
- 修改ui-select的options,将value设为布尔值:
ng-init="options = [{ value: true, label: 'Yes' },{ value: false , label: 'No' }]" - 保持repeat表达式不变,控制器初始值维持布尔类型
$scope.isFinalSubmission = true,此时模型绑定无类型冲突。
验证方法
在控制器中添加监听,确认模型值是否正确更新:
$scope.$watch('isFinalSubmission', function(newVal, oldVal) { console.log('isFinalSubmission updated:', newVal, typeof newVal); });
选择下拉选项后,查看控制台输出,确认新值和类型符合预期。
内容的提问来源于stack exchange,提问作者Abhishek Sharma
相关产品推荐
相关产品推荐

