Angular中赋值国家ID到$scope.mid报错‘Expression is non-assignable’求助
我来帮你搞定这个AngularJS下拉框绑定的问题,你之前踩的坑其实是没搞对AngularJS里select组件的正确绑定方式,咱们一步步理清楚:
1. 为什么最初的代码会报错?
你之前在<option>标签上写ng-model="mid = s.id"是完全错误的用法:
ng-model的作用是绑定一个scope变量,不能直接写赋值表达式(比如mid = s.id),AngularJS会认为这是不可赋值的表达式,所以抛出了Expression 'mid = s.id' is non-assignable的错误。- 而且
ng-model应该绑定在<select>标签上,而不是单个<option>——因为整个下拉控件的选中状态是由select管理的,option只是选项列表。
2. 正确的实现方案(推荐用ng-options,更符合AngularJS规范)
AngularJS提供了ng-options指令专门用于生成select的选项,比手动用ng-repeat更简洁,也更符合数据绑定的逻辑。
控制器代码调整:
// 假设你的getCountries会填充这个国家列表 $scope.countries = []; // 绑定选中的国家对象(推荐绑定整个对象,方便获取ID和名称) $scope.selectedCountry = null; // 初始化默认的mid值 $scope.mid = 1; // 修改logId函数,返回当前选中的国家ID $scope.logId = function() { // 如果有选中的国家,就用它的ID,否则保留默认值1 $scope.mid = $scope.selectedCountry ? $scope.selectedCountry.id : 1; console.log($scope.mid); return $scope.mid; }; // getStates直接使用当前选中的国家ID $scope.getStates = function() { const currentCountryId = $scope.selectedCountry ? $scope.selectedCountry.id : null; if (currentCountryId) { // 这里写你的获取州列表逻辑,比如调用API // 示例:$http.get(`/api/states?countryId=${currentCountryId}`).then(res => { $scope.states = res.data; }); } };
HTML代码调整:
<div> <select ng-click="getCountries()" ng-model="selectedCountry" ng-options="country as country.name for country in countries" formcontrol name="country" class="ng-untouched ng-pristine ng-valid" required> <!-- 可选:添加默认提示选项 --> <option value="">请选择国家</option> </select> </div> <div ng-class="{'has-error': frmValidation.state.$invalid && !frmValidation.state.$pristine}" class="field required"> <label>State</label> <select ng-change="getStates()" ng-model="reg.state" formcontrol name="state" class="ng-untouched ng-pristine ng-invalid" required> <option value="">请选择州</option> <option ng-repeat="s in states" value="{{s.name}}">{{s.name}}</option> </select> </div>
3. 如果坚持用ng-repeat生成选项(不推荐,但可以调整)
如果你不想用ng-options,也可以保留ng-repeat,但必须把ng-model绑定在<select>上,通过option的value传递国家ID:
控制器代码:
// 初始化默认mid值 $scope.mid = 1; $scope.logId = function() { console.log($scope.mid); return $scope.mid; }; $scope.getStates = function() { if ($scope.mid) { // 用当前的mid值获取州列表 } };
HTML代码:
<select ng-click="getCountries()" ng-model="mid" formcontrol name="country" class="ng-untouched ng-pristine ng-valid" required> <!-- 默认选项对应初始mid=1 --> <option value="1">默认国家</option> <option ng-repeat="s in countries" value="{{s.id}}">{{s.name}}</option> </select> <div ng-class="{'has-error': frmValidation.state.$invalid && !frmValidation.state.$pristine}" class="field required"> <label>State</label> <select ng-change="getStates()" ng-model="reg.state" formcontrol name="state" required> <option value="">请选择州</option> <option ng-repeat="s in states" value="{{s.name}}">{{s.name}}</option> </select> </div>
关键注意点:
- 用
ng-change代替ng-click触发getStates:ng-click会在点击select控件本身时就触发,而ng-change只有当选中项真正变化时才触发,逻辑更准确。 - 始终遵循AngularJS的数据绑定原则:让scope变量和视图双向绑定,不要手动通过ng-click去赋值,这样能避免很多奇怪的问题。
内容的提问来源于stack exchange,提问作者rocket
相关产品推荐
相关产品推荐

