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

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

相关产品推荐
方舟 Agent Plan

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

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