AngularJS和null选择值依赖于选择顺序

AngularJS and null select values dependent on selection order

本文关键字:选择 依赖于 顺序 AngularJS null      更新时间:2023-09-26

我试图理解我在AngularJS中注意到的一个特别奇怪的行为。下面是演示这个问题的基本代码片段:

(function (angular) {
  var module = angular.module('test', []);
  
  module.controller('TestCtrl', ['$scope', function ($scope) {
    $scope.channels = [
      { name: 'A', id: 1, defSource: 'Y' },
      { name: 'B', id: 2 },
      { name: 'C', id: 3, defSource: 'Z' },
    ];
    $scope.sources = [ 'X', 'Y', 'Z' ];
    $scope.model = {};
    
    $scope.channelChanged = function() {
      $scope.model.source = $scope.model.channel.defSource;
    };
  }]);
  
})(angular);
        
angular.element(document).ready(function () {
  angular.bootstrap(document, ['test']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.28/angular.min.js"></script>
<form ng-controller="TestCtrl">
  <div>
    <label>Channel: <select ng-model="model.channel"
                            ng-options="channel.name for channel in channels"
                            ng-change="channelChanged()"></select></label>
  </div>
  <div>
    <label>Source: <select ng-model="model.source"
                           ng-options="source for source in sources"></select></label>
  </div>
  <br />
  <div>Channel = {{model.channel}}</div>
  <div>Source = {{model.source}}</div>
</form>

观察到的行为(使用Chrome)是这样的:

  1. 选择通道A;它会自动选择源"Y"。
  2. 选择通道B;它自动选择一个空源。
  3. 选择通道"C";它仍然是一个空源,而不是像预期的那样选择"Z"。
  4. 选择通道A;按预期选择"Y"
  5. 选择通道"C";按预期选择"Z"
  6. 选择通道B;它按预期选择null,但现在选择包含两个空白值。

在所有情况下,模型中的值都是正确的;只是UI最终表现得很奇怪。

我可以通过显式地提供一个<option>元素来表示源选择中的null来解决这个问题,但我不明白为什么这个代码具有这种行为,特别是"C"的两种不同行为取决于先前的选择,以及为什么"A"不做同样的事情。这是一个已知的AngularJS或Chrome bug还是我错过了什么?

这是你正在使用的Angular版本中的一个bug。请尝试使用1.3的最新版本,即1.3.17

(function (angular) {
  var module = angular.module('test', []);
  
  module.controller('TestCtrl', ['$scope', function ($scope) {
    $scope.channels = [
      { name: 'A', id: 1, defSource: 'Y' },
      { name: 'B', id: 2 },
      { name: 'C', id: 3, defSource: 'Z' },
    ];
    $scope.sources = [ 'X', 'Y', 'Z' ];
    $scope.model = {};
    
    $scope.channelChanged = function() {
      $scope.model.source = $scope.model.channel.defSource;
    };
  }]);
  
})(angular);
        
angular.element(document).ready(function () {
  angular.bootstrap(document, ['test']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.17/angular.min.js"></script>
<form ng-controller="TestCtrl">
  <div>
    <label>Channel: <select ng-model="model.channel"
                            ng-options="channel.name for channel in channels"
                            ng-change="channelChanged()"></select></label>
  </div>
  <div>
    <label>Source: <select ng-model="model.source"
                           ng-options="source for source in sources"></select></label>
  </div>
  <br />
  <div>Channel = {{model.channel}}</div>
  <div>Source = {{model.source}}</div>
</form>