带有禁用行的ng选项
是否有可能使用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)">
并让我们说,通过一个filter,可能会返回disabled='disabled'
的所有颜色的阴影=“黑暗”
<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>
@ lucuma的回答(最初是被接受的答案)是正确的,但现在应该更新,因为这是固定的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];
正如@Lod Angular所指出的,在1.4.0-beta.5中增加了对此的支持。
对于angular度js > = 1.4.0-beta.5 。
<select ng-options="c.name disable when c.shade == 'dark' group by c.shade for c in colors">
而对于angularjs <1.4.0-beta.5请参考下面的解决scheme:
类似于@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); }); } }; });
注意 :这个解决scheme不适用于group by
正如所有人都指出的那样。 如果您正在使用group by
工作,请参考@DHlavaty下面的解决scheme。
Angular在1.4.0-beta.5中增加了对此的支持
<select ng-options="c.name disable when c.shade == 'dark' group by c.shade for c in colors">
我不相信有一种方法可以使用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'; }
自2015年2月以来,有一种方法可以禁用ng选项标签中的选项。
这个链接显示了在github上添加的function
我发现,使用angular1.4.7,语法已经从“禁用”改为“禁用时”。
这个语法是:
'ng-options': 'o.value as o.name disable when o.unavailable for o in options'
对选项本身使用ng-repeat
和ng-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 }); }
小提琴
已知的问题:
- 不使用
ng-options
- 不能和
group by
工作 - select索引,而不是对象
- 初始select需要
$timeout
我有一个有趣的情况。 一个下拉列表,我需要它来禁用已经在每个下拉菜单中select的选项,但是我也需要它来保持已经被选中的选项。
这里是我的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>
类似“没有jQuery”解决scheme@ Vikas-Gulati的,但它与group by
工作
在我的情况下, group by
不起作用,因为我的第一个<option>
是没有价值的,只需Please select and item from dropdown
文本中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); }); } }; });
你可以禁止在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}];
})
由于我无法升级到最新的angularJS,所以创build了一个更简单的指令来处理它。
.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
我也隐藏了禁用的选项添加休闲线:
$(this).css("display", fnDisableIfTrue(scope, locals) ? "none" : "block");
这是必要的,因为我不能简单地过滤出来,因为这个select的初始值可能是残疾选项之一。