Ist es möglich, ng-options
zu verwenden, der basierend auf Kriterien in deaktivierte Zeilen gerendert wird?
diese:
<select ng-options="c.name group by c.shade for c in colors">
vielleicht möglich, so etwas zu machen:
<select ng-options="c.name group by c.shade for c in colors | disabled(c.shade)">
und lassen Sie uns über einen Filter sagen, der disabled='disabled'
für alle Farben zurückgeben könnte, die Schatten haben = "dunkel"
<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>
Die Antwort von @ lucuma (ursprünglich die akzeptierte Antwort) war korrekt, sollte jedoch jetzt aktualisiert werden, da dies in Angular 1.4 behoben wurde. Siehe docs von ng-options , das auch ein example enthält.
Ich verwende Angular 1.5 und das funktioniert für mich:
<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];
Wie von @Lod Angular hervorgehoben, wurde in 1.4.0-beta.5 Unterstützung dafür hinzugefügt.
Für Winkel js > = 1.4.0-beta.5.
<select ng-options="c.name disable when c.shade == 'dark'
group by c.shade for c in colors">
Und für Winkel js <1.4.0-beta.5 beziehen Sie sich auf die Lösung unten:
Ähnlich wie in @lucuma aber ohne jQuery-Abhängigkeit.
Überprüfen Sie dies http://jsfiddle.net/dZDLg/46/
Controller
<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>
Richtlinie
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);
});
}
};
});
Note: Diese Lösung funktioniert nicht mit group by
, wie von allen zu Recht angegeben. Beziehen Sie sich auf die Lösung unter @DHlavaty , wenn Sie mit group by
arbeiten wollen.
Angular fügte Unterstützung in 1.4.0-beta.5 hinzu
<select ng-options="c.name disable when c.shade == 'dark' group by c.shade for c in colors">
Ich glaube nicht, dass es eine Möglichkeit gibt, das zu tun, was Sie gerade mit ng-options
verlangen. Dieses Problem wurde im Winkelprojekt angesprochen und ist noch offen:
https://github.com/angular/angular.js/issues/638
Anscheinend besteht die Arbeit darin, eine Direktive zu verwenden, auf die hier und in der Github-Ausgabe verwiesen wird: http://jsfiddle.net/alalonde/dZDLg/9/
Hier ist der gesamte Code von jsfiddle als Referenz (der Code unten stammt von alandes 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';
}
Seit Februar 2015 gibt es eine Möglichkeit, Optionen in Ihrem ng-options-Tag zu deaktivieren.
Dieser Link zeigt das Hinzufügen des Features auf github
Ich habe festgestellt, dass sich die Syntax mit Winkel 1.4.7 von 'disable by' auf 'disable when' geändert hat.
Die Syntax dafür lautet:
'ng-options': 'o.value as o.name disable when o.unavailable for o in options'
Ein ähnlicher Effekt kann mit ng-repeat
und ng-disabled
für die Option selbst erzielt werden, sodass keine neue Direktive verwendet werden kann.
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>
Controller
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
});
}
Fiddle
Bekannte Probleme:
ng-options
nichtgroup by
$timeout
für die erste AuswahlIch hatte eine interessante Situation. Eine Reihe von Dropdowns, und ich brauche es, um die Optionen zu deaktivieren, die bereits in den Dropdowns ausgewählt wurden. Ich brauche es aber auch, um die bereits ausgewählte Option zu aktivieren.
hier ist mein plunker: Werte mit ng-Optionen aktivieren/deaktivieren
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="[email protected]" 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>
Ähnliche "without jQuery" -Lösung wie @ Vikas-Gulati s, aber es funktioniert mit group by
In meinem Fall funktioniert group by
nicht, da mein erster <option>
ohne Wert war, nur mit Please select and item from dropdown
-Text. Dies ist eine leicht modifizierte Version, die diese besondere Situation behebt:
Die Verwendung von @ Vikas-Gulati entspricht in etwa der Antwort: https://stackoverflow.com/a/20790905/1268533
Richtlinie
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);
});
}
};
});
Sie können die Verwendung von ngOptions in Winkel 1.4.1 oder höher deaktivieren
<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}];
})
Da ich kein Upgrade auf die neueste Version von angleJS durchführen kann, wurde eine einfachere Direktive erstellt.
.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');
}
}
});
}
}])
für weitere Details: https://github.com/farazshuja/disabled-options
Ich habe auch deaktivierte Optionen versteckt, die folgende Zeile hinzufügen:
$(this).css("display", fnDisableIfTrue(scope, locals) ? "none" : "block");
Es war notwendig, da ich sie nicht einfach herausfiltern konnte, da der Anfangswert dieser Auswahl eine der deaktivierten Optionen sein könnte.