天天看點

angularjs select标簽中ng-model無法在js controller中取值問題

<div class="col-md-4">					
  <label class="col-md-3">周次:</label>
  <ui-select class="col-md-9" ng-model="week" theme="bootstrap" ng-change='loadTable()'>
    <ui-select-match placeholder="選擇周次" class="boNone"> 
      {{$select.selected}} 
    </ui-select-match>
    <ui-select-choices repeat="w in weeks | filter:$select.search "> 
      {{w}} 
    </ui-select-choices> 
  </ui-select>
</div>
           
$scope.loadTable = function() {
  alert($scope.week);
}
           

如上,weeks的值類似[1,2,3]這種結構,初始化代碼略。使用angularjs的ui-select插件寫了一個選擇周次的下拉框,但使用時可以正常顯示值,也可以正常選擇,但選擇後背景卻不能取到正确的值,使用彈出框調試後發現$scope.week的值是undefined。

修改為以下代碼後可以正常取值:

<div class="col-md-4">					
  <label class="col-md-3">周次:</label>
  <ui-select class="col-md-9" ng-model="params.week" theme="bootstrap" ng-change='loadTable()'>
    <ui-select-match placeholder="選擇周次" class="boNone"> 
      {{$select.selected}} 
    </ui-select-match>
    <ui-select-choices repeat="w in weeks | filter:$select.search "> 
      {{w}} 
    </ui-select-choices> 
  </ui-select>
</div>
           
$scope.loadTable = function() {
  alert($scope.params.week);
}
           

原因:

1.由于原型繼承的關系,修改父級對象中的someBareValue會同時修改子對象中的值,但反之則不行。

2.ng-if 以及 ng-repeat 會建立一個子級作用域,如果在這倆個指令中添加了元素,并增加ng-model指令,那麼ng-model對應的作用域屬于子級作用域,并非controller注入的$scope對應的作用域。

解決:

1.方法一:先定義一個params對象(名稱随意),如$scope.params={},然後其他代碼按照前面能正常使用的代碼進行書寫。

現對前面的例子進行分析,當直接定義在$scope下時,如果js中寫了$scope.week=1,則頁面加載後下拉框選中項會是1(例子中未定義week,故設定不成功時取值是undefined),這意味着父$scope中設定的值在子$scope中是生效的,因為子week繼承自父week,然後點選下拉框選中2,這種情況下因為設定過了,彈出框不會再顯示undefined了,但此時彈出框依然彈出1,這就意味着子$scope中設定的值不會對父$scope生效,符合前面分析的原因,即此時父$scope.week=1,子$scope.week=2(子對象已經改變了)。彈出的是父$scope.week的值。當将week定義為$scope中params對象的一個屬性時,子params繼承自父params,當修改子params中的week屬性時(子對象并未改變,還是繼承過來的那個對象),故修改的week會通過引用進行共享,是以在子$scope中修改屬性也會修改父$scope中的這個屬性。

2.方法二:js取值依然按照$scope.week取值,頁面下拉框綁定資料修改為ng-model="$parent.week"。

此種方式将子作用域中的值直接綁定到父作用域中,故在js中能夠直接使用。

實際使用建議使用方法一,否則當存在很多層作用域時容易出問題。