2

最初のドロップダウン選択に基づいて2番目のドロップダウンが表示されるカスケード選択があります。ドロップダウンの意図した動作の一部ではない余分な空白のオプションが表示されます。

<select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" 
    data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses"> 
</select>

空の余分な選択がドロップダウンに表示されないようにするにはどうすればよいですか?

ここに画像の説明を入力

私のカスケードドロップダウンのコードは

    <div class="form-group" ng-class="{ 'has-error' : submitted && orderForm.content.$invalid}">
      <div class="controls">
        <select ng-change="getSubStatuses(order.attempt_status)" data-ng-model="order.attempt_status" ng-options="status.name as status.name for status in statuses">
        </select>
      </div>
    </div>

    <div class="form-group" ng-show="subStatuses.length" ng-class="{ 'has-error' : submitted && orderForm.content.$invalid}">
      <div class="controls">
        <select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as subStatus.name for subStatus in subStatuses">
        </select>
      </div>
    </div>
$scope.getSubStatuses = function(attempt_status) {

    var statuses = $scope.statuses;
    for(var index in statuses) {
        if(statuses[index].name === attempt_status) {

            if(statuses[index].children) {
                $scope.subStatuses = statuses[index].children;
            } else {
                $scope.subStatuses = [];
            }
            break;
        }
    }
};
4

1 に答える 1

4

非同期にバインドされたデータに対してこれを設定していると仮定しています。ng-initこの目的には本当に悪いです。親指のルールはng-init、コントローラーが行うべきことには使用しないでください。コントローラーでビューモデルを設定する必要があります。データが非同期にバインドされているときに失敗する可能性がある理由は、ng-init'ed 式が監視されていないためです。そのため、最初のレンダリング中に 1 回だけ実行され、subStatusesまだ入力されておらず、デフォルトの空のオプションを表示するようにフォールバックします。また、後のダイジェスト サイクル中にデータが入力され、ビューが更新されたとしても、ng-init 式は再度実行されません。

ドクから

ngInit の唯一の適切な使用法は、以下のデモに見られるように、ngRepeat の特別なプロパティをエイリアシングすることです。この場合とは別に、ngInit ではなくコントローラーを使用して、スコープの値を初期化する必要があります。

したがって、ng-init を使用する代わりに、コントローラーで初期化するだけです。

$scope.getSubStatuses = function(attempt_status) {

    var statuses = $scope.statuses;
    for(var index in statuses) {
        if(statuses[index].name === attempt_status) {

            if(statuses[index].children) {
                $scope.subStatuses = statuses[index].children;
            } else {
                $scope.subStatuses = [];
            }
            break;
        }
    }
    //Initialize the model here, assuming $scope.order is already initialized
    $scope.order.attempt_status_sub = ($scope.subStatuses[0] ||{}).name;
};

angular.module('app', []).controller('ctrl', function($scope, $timeout) {

  $timeout(function() {
    $scope.subStatuses = [{
      name: 'test1'
    }, {
      name: 'test2'
    }, {
      name: 'test3'
    }];

    $scope.order = {
      attempt_status_sub1: $scope.subStatuses[0].name
    };

  });



});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
  With Ng-Init
  <select ng-init="order.attempt_status_sub = order.attempt_status_sub || subStatuses[0].name" data-ng-model="order.attempt_status_sub" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses">
  </select>

  With controller initialization.

  <select data-ng-model="order.attempt_status_sub1" ng-options="subStatus.name as 
    subStatus.name for subStatus in subStatuses">
  </select>
</div>

于 2015-01-12T19:29:05.927 に答える