59

是否可以使用ng-options它将根据标准呈现为禁用的行?

这个:

 <select ng-options="c.name group by c.shade for c in colors">

也许有可能变成这样的东西:

 <select ng-options="c.name group by c.shade for c in colors | disabled(c.shade)">

假设通过一个过滤器可以返回disabled='disabled'所有具有 shade = "dark" 的颜色

<select>
   <optgroup label="dark">
      <option value="0" disabled="disabled">black</option>
      <option value="2" disabled="disabled">red</option>
      <option value="3" disabled="disabled">blue</option>
   </optgroup>
   <optgroup label="light">
      <option value="1">white</option>
      <option value="4">yellow</option>
   </optgroup>
 </select>
4

11 回答 11

66

@lucuma 的答案(最初被接受的答案)是正确的,但现在应该更新,因为这已在 Angular 1.4 中修复。请参阅ng-options 的文档,其中还包含一个示例

我正在使用 Angular 1.5,这对我有用:

看法

<select ng-model="$ctrl.selectedItem" ng-options="item as item.label disable when item.disabled for item in $ctrl.listItems">

控制器

vm.items = [ { id: 'optionA', label: 'Option A' }, { id: 'optionB', label: 'Option B (recommended)' }, { id: 'optionC', label: 'Option C (Later)', disabled: true } ]; vm.selectedItem = vm.items[1];

于 2016-11-01T07:31:10.007 回答
55

正如@Lod Angular 所指出的,在 1.4.0-beta.5 中增加了对此的支持。

对于角度 js >= 1.4.0-beta.5

<select ng-options="c.name disable when c.shade == 'dark' 
group by c.shade for c in colors">

对于 angular js < 1.4.0-beta.5,请参考以下解决方案:

与@lucuma给出的类似,但没有 jQuery 依赖项。

检查这个http://jsfiddle.net/dZDLg/46/

控制器

<div ng-controller="OptionsController">
    <select ng-model="selectedport" 
        ng-options="p.name as p.name for p in ports"
        options-disabled="p.isinuse for p in ports"></select>
    <input ng-model="selectedport">
</div>

指示

angular.module('myApp', [])
.directive('optionsDisabled', function($parse) {
    var disableOptions = function(scope, attr, element, data, 
                                  fnDisableIfTrue) {
        // refresh the disabled options in the select element.
        var options = element.find("option");
        for(var pos= 0,index=0;pos<options.length;pos++){
            var elem = angular.element(options[pos]);
            if(elem.val()!=""){
                var locals = {};
                locals[attr] = data[index];
                elem.attr("disabled", fnDisableIfTrue(scope, locals));
                index++;
            }
        }
    };
    return {
        priority: 0,
        require: 'ngModel',
        link: function(scope, iElement, iAttrs, ctrl) {
            // parse expression and build array of disabled options
            var expElements = iAttrs.optionsDisabled.match(
                /^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/);
            var attrToWatch = expElements[3];
            var fnDisableIfTrue = $parse(expElements[1]);
            scope.$watch(attrToWatch, function(newValue, oldValue) {
                if(newValue)
                    disableOptions(scope, expElements[2], iElement, 
                        newValue, fnDisableIfTrue);
            }, true);
            // handle model updates properly
            scope.$watch(iAttrs.ngModel, function(newValue, oldValue) {
                var disOptions = $parse(attrToWatch)(scope);
                if(newValue)
                    disableOptions(scope, expElements[2], iElement, 
                        disOptions, fnDisableIfTrue);
            });
        }
    };
});

注意:此解决方案不适用于group by每个人都正确指出的问题。如果您想让group by.

于 2013-12-26T20:34:24.457 回答
26

Angular 在 1.4.0-beta.5 中添加了对此的支持

<select ng-options="c.name disable when c.shade == 'dark' group by c.shade for c in colors">
于 2015-04-08T08:23:47.937 回答
15

我不相信有一种方法可以做你所要求的只是使用ng-options. 这个问题是在 Angular 项目中提出的,并且仍然存在:

https://github.com/angular/angular.js/issues/638

似乎解决方法是使用此处和 github 问题中引用的指令:http: //jsfiddle.net/alalonde/dZDLg/9/

这是来自 jsfiddle 的完整代码供参考(下面的代码来自 alande 的 jsfiddle):

<div ng-controller="OptionsController">
    <select ng-model="selectedport" 
        ng-options="p.name as p.name for p in ports"
        options-disabled="p.isinuse for p in ports"></select>
    <input ng-model="selectedport">
</div>

angular.module('myApp', [])
.directive('optionsDisabled', function($parse) {
    var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) {
        // refresh the disabled options in the select element.
        $("option[value!='?']", element).each(function(i, e) {
            var locals = {};
            locals[attr] = data[i];
            $(this).attr("disabled", fnDisableIfTrue(scope, locals));
        });
    };
    return {
        priority: 0,
        require: 'ngModel',
        link: function(scope, iElement, iAttrs, ctrl) {
            // parse expression and build array of disabled options
            var expElements = iAttrs.optionsDisabled.match(/^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/);
            var attrToWatch = expElements[3];
            var fnDisableIfTrue = $parse(expElements[1]);
            scope.$watch(attrToWatch, function(newValue, oldValue) {
                if(newValue)
                    disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue);
            }, true);
            // handle model updates properly
            scope.$watch(iAttrs.ngModel, function(newValue, oldValue) {
                var disOptions = $parse(attrToWatch)(scope);
                if(newValue)
                    disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue);
            });
        }
    };
});

function OptionsController($scope) {
    $scope.ports = [{name: 'http', isinuse: true},
                    {name: 'test', isinuse: false}];

    $scope.selectedport = 'test';
}
于 2013-04-24T22:49:33.753 回答
7

使用选项本身可以实现类似的效果ng-repeatng-disabled避免使用新指令。

HTML

<div ng-controller="ExampleController">
    <select ng-model="myColor">
        <option ng-repeat="c in colors" ng-disabled="c.shade=='dark'" value="{{$index}}">
            {{c.name}}
        </option>
    </select>
</div>

控制器

function ExampleController($scope, $timeout) {
    $scope.colors = [
      {name:'black', shade:'dark'},
      {name:'white', shade:'light'},
      {name:'red', shade:'dark'},
      {name:'blue', shade:'dark'},
      {name:'yellow', shade:'light'}
    ];
    $timeout(function() {
        $scope.myColor = 4; // Yellow
    });
}

小提琴

http://jsfiddle.net/0p4q3b3s/

已知的问题:

  • 不使用ng-options
  • 不适用于group by
  • 选择索引,而不是对象
  • 需要$timeout初始选择

编辑: 可以选择任何对象属性(除了索引),但不能选择对象本身。此外,如果您有一个简单的数组而不是对象数组,则以下方法将起作用。

在 HTML 中更改此行:

<option ng-repeat="c in colors" ng-disabled="c.shade=='dark'" value="{{c.name}}">

在 Controller 中更改此行:

$scope.myColor = $scope.colors[4].name; // Yellow
于 2014-09-26T15:04:38.367 回答
7

自 2015 年 2 月以来,有一种方法可以禁用 ng-options 标签中的选项。

此链接显示了在 github 上添加的功能

我发现使用 angular 1.4.7,语法已经从“禁用”更改为“禁用时间”。

其语法是:

'ng-options': 'o.value as o.name disable when o.unavailable for o in options'
于 2015-11-23T16:07:46.357 回答
3

我遇到了一个有趣的情况。一组下拉列表,我需要它来禁用每个下拉列表中已经选择的选项,但我还需要它来保持启用已经选择的选项......

这是我的 plunker: 使用 ng-options 启用/禁用值

var app = angular.module('ngoptions', []);

app.controller('MainCtrl', function($scope) {

  // disable the fields by default
  $scope.coverage = [
    { CoverageType: '', CoverageName: 'No Coverage' },
    { CoverageType: 'A', CoverageName: 'Dependent Only' },
    { CoverageType: 'B', CoverageName: 'Employee Plus Children' },
    { CoverageType: 'C', CoverageName: 'Employee Only' },
    { CoverageType: 'D', CoverageName: 'Employee Plus One' },
    { CoverageType: 'E', CoverageName: 'Employee Plus Two' },
    { CoverageType: 'F', CoverageName: 'Family' },
];
            
            
  // values already set ex: pulled from db          
  $scope.rates = ['A','C', 'F'];     

  $scope.changeSelection = function (index, rate){
     $scope.rates[index] = rate;
     disableRecords();
  }
  
  // start by disabling records
  disableRecords(); 
  
  function disableRecords () {
      // set default values to false
      angular.forEach($scope.coverage, function (i, x) {
             i.disable = false; 
      });
      // set values to true if they exist in the array
      angular.forEach($scope.rates, function (item, idx) {
          angular.forEach($scope.coverage, function (i, x) {
              if (item == i.CoverageType) {
                   i.disable = true; 
              }
          });
      });
  }
  

});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.min.js"></script>
<!DOCTYPE html>
<html ng-app="ngoptions">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script data-require="angular.js@1.4.7" data-semver="1.4.7" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.js"></script>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <table>
      <thead></thead>
      <tbody>
        <tr ng-repeat="rate in rates">
          <td>
            <select 
            ng-model="rate" 
            ng-change="changeSelection($index, rate)" 
            ng-options="type.CoverageType as type.CoverageName disable when (type.disable == true && type.CoverageType != rate) for type in coverage"></select>
          </td>
        </tr>
      </tbody>
    </table>
  </body>

</html>

于 2015-11-04T20:24:18.367 回答
3

您可以在 Angular 1.4.1 或更高版本中禁用使用 ngOptions

HTML 模板

<div ng-app="myapp">
<form ng-controller="ctrl">
    <select id="t1" ng-model="curval" ng-options='reportingType.code as reportingType.itemVal disable when reportingType.disable for reportingType in reportingOptions'>
        <option value="">Select Report Type</option>
    </select>

</form>

控制器代码

angular.module('myapp',[]).controller("ctrl", function($scope){
$scope.reportingOptions=[{'code':'text','itemVal':'TEXT','disable':false}, {'code':'csv','itemVal':'CSV','disable':true}, {'code':'pdf','itemVal':'PDF','disable':false}];

})

于 2016-04-20T08:12:56.430 回答
2

与@Vikas-Gulati类似的“无 jQuery”解决方案,但它适用于group by

在我的情况下,group by不起作用,因为我的第一个<option>没有价值,只有Please select and item from dropdown文字。这是一个稍作修改的版本,修复了这种特殊情况:

用法类似于@Vikas-Gulati 答案:https ://stackoverflow.com/a/20790905/1268533

指示

angular.module('disabledModule', [])
    .directive('optionsDisabled', function($parse) {
        var disableOptions = function(scope, attr, element, data, fnDisableIfTrue) {
            var realIndex = 0;
            angular.forEach(element.find("option"), function(value, index){
                var elem = angular.element(value);
                if(elem.val()!="") {
                    var locals = {};
                    locals[attr] = data[realIndex];
                    realIndex++; // this skips data[index] with empty value (IE first <option> with 'Please select from dropdown' item)
                    elem.attr("disabled", fnDisableIfTrue(scope, locals));
                }
            });
        };
        return {
            priority: 0,
            require: 'ngModel',
            link: function(scope, iElement, iAttrs, ctrl) {
                // parse expression and build array of disabled options
                var expElements = iAttrs.optionsDisabled.match(/^\s*(.+)\s+for\s+(.+)\s+in\s+(.+)?\s*/);
                var attrToWatch = expElements[3];
                var fnDisableIfTrue = $parse(expElements[1]);
                scope.$watch(attrToWatch, function(newValue, oldValue) {
                    if(newValue)
                        disableOptions(scope, expElements[2], iElement, newValue, fnDisableIfTrue);
                }, true);
                // handle model updates properly
                scope.$watch(iAttrs.ngModel, function(newValue, oldValue) {
                    var disOptions = $parse(attrToWatch)(scope);
                    if(newValue)
                        disableOptions(scope, expElements[2], iElement, disOptions, fnDisableIfTrue);
                });
            }
        };
    });
于 2014-12-08T15:21:03.687 回答
1

由于我无法升级到最新的 angularJS,所以创建了一个更简单的指令来处理它。

.directive('allowDisabledOptions',['$timeout', function($timeout) {
    return function(scope, element, attrs) {
        var ele = element;
        var scopeObj = attrs.allowDisabledOptions;
        $timeout(function(){
            var DS = ele.scope()[scopeObj];
            var options = ele.children();
            for(var i=0;i<DS.length;i++) {
                if(!DS[i].enabled) {
                    options.eq(i).attr('disabled', 'disabled');
                }
            }
        });
    }
}])

更多详情:https ://github.com/farazshuja/disabled-options

于 2015-09-30T11:01:33.750 回答
1

我还隐藏了添加休闲线的禁用选项:

$(this).css("display", fnDisableIfTrue(scope, locals) ? "none" : "block");

这是必要的,因为我不能简单地将它们过滤掉,因为此选择的初始值可能是禁用的选项之一。

于 2015-10-22T10:55:28.610 回答