456 Stimmen

Arbeiten mit Select unter Verwendung der ng-options von AngularJS

Ich habe in anderen Beiträgen darüber gelesen, aber ich konnte es nicht herausfinden.

Ich habe ein Array,

$scope.items = [
   {ID: '000001', Title: 'Chicago'},
   {ID: '000002', Title: 'New York'},
   {ID: '000003', Title: 'Washington'},
];

Ich möchte es so wiedergeben:

<select>
  <option value="000001">Chicago</option>
  <option value="000002">New York</option>
  <option value="000003">Washington</option>
</select>

Außerdem möchte ich die Option mit der ID=000002 auswählen.

Ich habe gelesen Wählen Sie und versucht, aber ich kann es nicht herausfinden.

809voto

Ben Lesh Punkte 106494

Eine Sache, die zu beachten ist, ist, dass ngModel erforderlich damit ngOptions funktioniert... beachten Sie die ng-model="blah" was bedeutet: "setze $scope.blah auf den ausgewählten Wert".

Versuchen Sie dies:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

Hier ist mehr aus der AngularJS-Dokumentation (falls Sie sie noch nicht gesehen haben):

für Array-Datenquellen:

  • Bezeichnung für Wert in Array
  • als Bezeichnung für Wert in Array wählen
  • Etikett Gruppe nach Gruppe fo = select as label group by group für Wert in array

für Objektdatenquellen:

  • label for (Schlüssel , Wert) in object
  • select as label für (Schlüssel , Wert) in object
  • label group by group for (Schlüssel, Wert) in object
  • select as label group by group for (Schlüssel, Wert) in object

Zur Erläuterung der Werte von Optionstags in AngularJS:

Wenn Sie ng-options , die Werte von Options-Tags, die von ng-options ausgegeben werden, sind immer der Index des Array-Elements, auf das sich das Options-Tag bezieht . Das liegt daran, dass AngularJS die Auswahl ganzer Objekte mit Auswahlsteuerelementen ermöglicht, und nicht nur primitiver Typen. Zum Beispiel:

app.controller('MainCtrl', function($scope) {
   $scope.items = [
     { id: 1, name: 'foo' },
     { id: 2, name: 'bar' },
     { id: 3, name: 'blah' }
   ];
});

<div ng-controller="MainCtrl">
   <select ng-model="selectedItem" ng-options="item as item.name for item in items"></select>
   <pre>{{selectedItem | json}}</pre>
</div>

Mit der obigen Funktion können Sie ein ganzes Objekt in $scope.selectedItem direkt. Der Punkt ist, dass Sie sich mit AngularJS nicht darum kümmern müssen, was in Ihrem Option-Tag steht. Lassen Sie AngularJS das erledigen; Sie sollten sich nur darum kümmern, was in Ihrem Modell in Ihrem Bereich ist.

Hier ist ein Plunker, der das oben beschriebene Verhalten demonstriert und den HTML-Code anzeigt


Umgang mit der Standardoption:

Es gibt ein paar Dinge, die ich oben nicht erwähnt habe, die sich auf die Standardoption beziehen.

Wählen Sie die erste Option und entfernen Sie die leere Option:

Sie können dies tun, indem Sie eine einfache ng-init die das Modell (von ng-model ) auf das erste Element der Elemente, die Sie in ng-options :

<select ng-init="foo = foo || items[0]" ng-model="foo" ng-options="item as item.name for item in items"></select>

Hinweis: Dies könnte ein wenig verrückt werden, wenn foo zufällig richtig auf etwas "Falsches" initialisiert wird. In diesem Fall müssen Sie die Initialisierung von foo in Ihrem Controller, höchstwahrscheinlich.

Anpassen der Standardoption:

Hier müssen Sie lediglich ein Optionstag als untergeordnetes Element Ihres Select-Tags mit einem leeren value-Attribut hinzufügen und dann den inneren Text anpassen:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="">Nothing selected</option>
</select>

Hinweis: In diesem Fall bleibt die Option "leer" bestehen, auch wenn Sie eine andere Option auswählen. Dies ist nicht der Fall für das Standardverhalten von Selects unter AngularJS.

Eine benutzerdefinierte Standardoption, die nach dem Treffen einer Auswahl ausgeblendet wird:

Wenn Sie möchten, dass Ihre angepasste Standardoption verschwindet, nachdem Sie einen Wert ausgewählt haben, können Sie ein ng-hide-Attribut zu Ihrer Standardoption hinzufügen:

<select ng-model="foo" ng-options="item as item.name for item in items">
   <option value="" ng-if="foo">Select something to remove me.</option>
</select>

90voto

mp31415 Punkte 6113

Ich lerne gerade AngularJS und hatte auch mit der Auswahl zu kämpfen. Ich weiß, dass diese Frage bereits beantwortet ist, aber ich wollte trotzdem etwas mehr Code teilen.

In meinem Test habe ich zwei Listboxen: Automarken und Automodelle. Die Liste der Modelle ist deaktiviert, bis eine Marke ausgewählt wird. Wenn die Auswahl in der Marken-Listbox später zurückgesetzt wird (auf "Marke auswählen"), wird die Modell-Listbox wieder deaktiviert UND ihre Auswahl wird ebenfalls zurückgesetzt (auf "Modell auswählen"). Die Marken werden als Ressource abgerufen, während die Modelle nur fest kodiert sind.

Erzeugt JSON:

[
{"code": "0", "name": "Select Make"},
{"code": "1", "name": "Acura"},
{"code": "2", "name": "Audi"}
]

services.js:

angular.module('makeServices', ['ngResource']).
factory('Make', function($resource){
    return $resource('makes.json', {}, {
        query: {method:'GET', isArray:true}
    });
});

HTML-Datei:

<div ng:controller="MakeModelCtrl">
  <div>Make</div>
  <select id="makeListBox"
      ng-model="make.selected"
      ng-options="make.code as make.name for make in makes"
      ng-change="makeChanged(make.selected)">
  </select>

  <div>Model</div>
  <select id="modelListBox"
     ng-disabled="makeNotSelected"
     ng-model="model.selected"
     ng-options="model.code as model.name for model in models">
  </select>
</div>

controllers.js:

function MakeModelCtrl($scope)
{
    $scope.makeNotSelected = true;
    $scope.make = {selected: "0"};
    $scope.makes = Make.query({}, function (makes) {
         $scope.make = {selected: makes[0].code};
    });

    $scope.makeChanged = function(selectedMakeCode) {
        $scope.makeNotSelected = !selectedMakeCode;
        if ($scope.makeNotSelected)
        {
            $scope.model = {selected: "0"};
        }
    };

    $scope.models = [
      {code:"0", name:"Select Model"},
      {code:"1", name:"Model1"},
      {code:"2", name:"Model2"}
    ];
    $scope.model = {selected: "0"};
}

41voto

Mattijs Punkte 3125

Aus irgendeinem Grund kann AngularJS mich verwirren. Ihre Dokumentation ist ziemlich schrecklich auf diese. Mehr gute Beispiele für Variationen wäre willkommen.

Wie auch immer, ich habe eine leichte Abwandlung der Antwort von Ben Lesh.

Meine Datensammlungen sehen wie folgt aus:

items =
[
   { key:"AD",value:"Andorra" }
,  { key:"AI",value:"Anguilla" }
,  { key:"AO",value:"Angola" }
 ...etc..
]

Jetzt

<select ng-model="countries" ng-options="item.key as item.value for item in items"></select>

führte immer noch dazu, dass der Wert der Optionen der Index war (0, 1, 2, usw.).

Hinzufügen von Spur von hat es für mich erledigt:

<select ng-model="blah" ng-options="item.value for item in items track by item.key"></select>

Ich denke, es kommt häufiger vor, dass man ein Array von Objekten in eine Auswahlliste einfügen will, also werde ich mir das merken!

Beachten Sie, dass Sie ab AngularJS 1.4 keine ng-options mehr verwenden können, sondern Sie müssen ng-repeat auf Ihrem Optionstag:

<select name="test">
   <option ng-repeat="item in items" value="{{item.key}}">{{item.value}}</option>
</select>

16voto

Tom Punkte 25050

Die Frage ist bereits beantwortet (übrigens eine wirklich gute und umfassende Antwort von Ben), aber ich möchte der Vollständigkeit halber noch ein weiteres Element hinzufügen, das ebenfalls sehr nützlich sein kann.

In dem von Ben vorgeschlagenen Beispiel:

<select ng-model="blah" ng-options="item.ID as item.Title for item in items"></select>

die folgenden ngOptions Form verwendet wurde: select as label for value in array .

Etikett ist ein Ausdruck, dessen Ergebnis die Bezeichnung für <option> Element. In diesem Fall können Sie bestimmte String-Verkettungen vornehmen, um komplexere Optionsbezeichnungen zu erhalten.

Beispiele:

  • ng-options="item.ID as item.Title + ' - ' + item.ID for item in items" gibt Ihnen Etiketten wie Title - ID
  • ng-options="item.ID as item.Title + ' (' + item.Title.length + ')' for item in items" gibt Ihnen Etiketten wie Title (X) , wobei X ist die Länge der Titelzeichenfolge.

Sie können z. B. auch Filter verwenden,

  • ng-options="item.ID as item.Title + ' (' + (item.Title | uppercase) + ')' for item in items" gibt Ihnen Etiketten wie Title (TITLE) wobei der Wert der Eigenschaften Title und TITLE derselbe Wert ist, aber in Großbuchstaben umgewandelt wird.
  • ng-options="item.ID as item.Title + ' (' + (item.SomeDate | date) + ')' for item in items" gibt Ihnen Etiketten wie Title (27 Sep 2015) wenn Ihr Modell eine Eigenschaft hat SomeDate

7voto

Akatsuki Sai Punkte 117

In CoffeeScript:

#directive
app.directive('select2', ->
    templateUrl: 'partials/select.html'
    restrict: 'E'
    transclude: 1
    replace: 1
    scope:
        options: '='
        model: '='
    link: (scope, el, atr)->
        el.bind 'change', ->
            console.log this.value
            scope.model = parseInt(this.value)
            console.log scope
            scope.$apply()
)

<!-- HTML partial -->
<select>
  <option ng-repeat='o in options'
          value='{{$index}}' ng-bind='o'></option>
</select>

<!-- HTML usage -->
<select2 options='mnuOffline' model='offlinePage.toggle' ></select2>

<!-- Conclusion -->
<p>Sometimes it's much easier to create your own directive...</p>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X