it-swarm.com.de

ng-Optionen mit deaktivierten Zeilen

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>
50
iLemming

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:

Aussicht

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

Regler

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]; 

46
Bart

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.

53
Vikas Gulati

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">
26
lod

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';
}
15
lucuma

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'
7
dafyddPrys

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

http://jsfiddle.net/0p4q3b3s/

Bekannte Probleme: 

  • Verwendet ng-options nicht
  • Funktioniert nicht mit group by
  • Wählt den Index aus, nicht das Objekt
  • Benötigt $timeout für die erste Auswahl
6
Wasmoo

Ich 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>

3

Ä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);
                });
            }
        };
    });
2
DHlavaty

Sie können die Verwendung von ngOptions in Winkel 1.4.1 oder höher deaktivieren

HTML-Vorlage

<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>

Controller-Code

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}];

})

2
Raja Rathinam

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

1
FarazShuja

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.

0
shagrin