Initialisierung der Auswahl mit AngularJS und ng-repeat

133

Ich versuche, das Auswahlfeld dazu zu bringen, mit einer vorgefüllten Option zu beginnen, indem ng-repeat mit AngularJS 1.1.5 verwendet wird. Stattdessen beginnt die Auswahl immer mit nichts ausgewähltem. Es hat auch eine leere Option, die ich nicht will. Ich denke, dass es einen Nebeneffekt gibt, wenn nichts ausgewählt wird.

Ich kann dies mit ng-options anstelle von ng-repeat zum Laufen bringen, aber ich möchte ng-repeat für diesen Fall verwenden. Obwohl mein eingegrenztes Beispiel es nicht zeigt, möchte ich auch das title-Attribut jeder Option festlegen, und soweit ich weiß, gibt es keine Möglichkeit, dies mit ng-options zu tun.

Ich glaube nicht, dass dies mit dem allgemeinen AngularJs-Problem mit dem Umfang / der prototypischen Vererbung zusammenhängt. Zumindest sehe ich bei der Inspektion in Batarang nichts Offensichtliches. Wenn Sie in der Auswahl mit der Benutzeroberfläche eine Option auswählen, wird das Modell außerdem korrekt aktualisiert.

Hier ist der HTML:

<body ng-app ng-controller="AppCtrl">
    <div>
        Operator is: {{filterCondition.operator}}
    </div>
    <select ng-model="filterCondition.operator">
       <option 
           ng-repeat="operator in operators" 
           value="{{operator.value}}"
       >
           {{operator.displayName}}
       </option>
    </select>
</body>

Und das JavaScript:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]
}

JS Fiddle dafür: http://jsfiddle.net/coverbeck/FxM3B/2/

Charles O.
quelle
1
ngOption wurde erstellt, weil es mit ngRepeat keine saubere Möglichkeit gab, dies zu tun. ngRepeat rollt ab, nachdem die Option ausgewählt wurde. Haben Sie versucht, ngSelect auf Ihre Optionen
einzustellen
Ja! Das ngSelected hat funktioniert! Ich werde eine aktualisierte funktionierende JsFiddle veröffentlichen.
Charles O.
Es ist zu beachten, dass dieser Code in AngualrJS 1.2 anders funktioniert. Er erstellt kein neues leeres <OPTION> -Element, kann jedoch nur die erste Option im Listenfeld auswählen. Sie können es hier sehen
VitalyB

Antworten:

226

OK. Wenn Sie nicht die richtige Methode verwenden möchten ng-options, können Sie ein ng-selectedAttribut mit einer Bedingungsprüflogik für die optionDirektive hinzufügen , damit die Vorauswahl funktioniert.

<select ng-model="filterCondition.operator">
    <option ng-selected="{{operator.value == filterCondition.operator}}"
            ng-repeat="operator in operators"
            value="{{operator.value}}">
      {{operator.displayName}}
    </option>
</select>

Working Demo

zs2020
quelle
37
Ich gebe Ihnen die Ehre, da Sie es selbst herausgefunden und das vollständige Beispiel gemacht haben. Obwohl ich Ihrem Kommentar nicht zustimme, dass ng-options der "richtige Weg" ist. :) Ich habe ng-options immer selbst verwendet, aber dafür musste etwas getan werden, das ng-options nicht unterstützt, so klein es auch ist. Und das Angular-Dokument sagt, dass Sie auch ng-repeat verwenden können. Vielen Dank, Charles
Charles O.
Vielen Dank, das war eine einfache Möglichkeit, einige Optionen zu deaktivieren.
Dorian
11
ng-options ist nur so lange korrekt, wie seine Anwendungsfälle zu Ihren passen. Möglicherweise benötigen Sie zusätzliche Attribute / Klassen in den Feldern Option / Optgruppe usw.
mystrdat
6
"der richtige Weg" funktioniert manchmal nicht (z. B. wenn Sie die Zeichenfolgen übersetzen möchten, die die Optionsnamen füllen)
btk
11
Ich denke, der ng-selected-Ausdruck muss ohne {{}} sein: ng-selected = "operator.value == filterCondition.operator"
mvermand
35

Für das Select-Tag stellt Angular die Direktive ng-options bereit. Es gibt Ihnen das spezifische Framework, um Optionen einzurichten und einen Standard festzulegen. Hier ist die aktualisierte Geige mit ng-Optionen, die wie erwartet funktioniert: http://jsfiddle.net/FxM3B/4/

Aktualisiertes HTML (Code bleibt gleich)

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.value as operator.displayName for operator in operators">
</select>
</body>
Jeremy Likness
quelle
3
Hallo Jeremy, ich versuche dies ohne ng-Optionen zu tun. Wie ich in meiner Frage und als Antwort auf Shaun sagte, möchte ich das title-Attribut für jede Option festlegen, und soweit ich weiß, kann ich das mit ng-options nicht tun. Vielen Dank, Charles
Charles O.
9

Vielen Dank an TheSharpieOne für den Hinweis auf die von ng ausgewählte Option. Wenn das eher als Antwort als als Kommentar gepostet worden wäre, hätte ich das zur richtigen Antwort gemacht.

Hier ist eine funktionierende JSFiddle: http://jsfiddle.net/coverbeck/FxM3B/5/ .

Ich habe auch die Geige aktualisiert, um das title-Attribut zu verwenden, das ich in meinem ursprünglichen Beitrag weggelassen hatte, da es nicht die Ursache des Problems war (aber es ist der Grund, warum ich ng-repeat anstelle von ng-options verwenden möchte). .

HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator}}</div>
<select ng-model="filterCondition.operator">
   <option ng-repeat="operator in operators" title="{{operator.title}}" ng-selected="{{operator.value == filterCondition.operator}}" value="{{operator.value}}">{{operator.displayName}}</option>
</select>
</body>

JS:

function AppCtrl($scope) {

    $scope.filterCondition={
        operator: 'eq'
    }

    $scope.operators = [
        {value: 'eq', displayName: 'equals', title: 'The equals operator does blah, blah'},
        {value: 'neq', displayName: 'not equal', title: 'The not equals operator does yada yada'}
     ]
}
Charles O.
quelle
Entschuldigung für das Posten als Kommentar. Ich hatte keine Lust, ein Beispiel zu geben, und ich war mir nicht 100% sicher, ob es funktionieren würde. Es war nur eine Ahnung.
TheSharpieOne
9

Die Tatsache, dass Angular ein leeres Optionselement in die Auswahl einfügt, besteht darin, dass das Modellobjekt, das standardmäßig daran gebunden ist, bei der Initialisierung einen leeren Wert enthält.

Wenn Sie eine Standardoption auswählen möchten, können Sie diese wahrscheinlich für den Bereich im Controller festlegen

$scope.filterCondition.operator = "your value here";

Wenn Sie einen leeren Optionsplatzhalter möchten, funktioniert dies für mich

<select ng-model="filterCondition.operator" ng-options="operator.id as operator.name for operator in operators">
  <option value="">Choose Operator</option>
</select>
Ammadu
quelle
2
Das ist gut, aber Angular erstellt eine leere Option. Wie vermeide ich das?
MarceloBarbosa
1

Wie vorgeschlagen müssen Sie ng-options verwenden, und ich glaube, Sie müssen leider auf das Array-Element als Standard verweisen (es sei denn, das Array ist ein Array von Zeichenfolgen).

http://jsfiddle.net/FxM3B/3/

Das JavaScript:

function AppCtrl($scope) {


    $scope.operators = [
        {value: 'eq', displayName: 'equals'},
        {value: 'neq', displayName: 'not equal'}
     ]

    $scope.filterCondition={
        operator: $scope.operators[0]
    }
}

Der HTML:

<body ng-app ng-controller="AppCtrl">
<div>Operator is: {{filterCondition.operator.value}}</div>
<select ng-model="filterCondition.operator" ng-options="operator.displayName for operator in operators">
</select>
</body>
Shaunhusain
quelle
Weißt du warum und bist du dir sicher? In der Dokumentation ( docs.angularjs.org/api/ng.directive:select ) heißt es, dass Sie ng-Optionen nur verwenden müssen, wenn Sie an einen Wert ohne Zeichenfolge binden. Wie gesagt, ich möchte das title-Attribut verwenden, und mit ng-options gibt es keine Möglichkeit, dies zu tun. So etwas wie <option title = "Eine sehr lange Beschreibung dieser Auswahl" ...> Danke.
Charles O.
Ich glaube, der Hinweis in den Dokumenten ist etwas unklar und bedeutet tatsächlich, dass Sie eine Zeichenfolge für das Modell verwenden und eine Reihe von Zeichenfolgen für die Optionen haben müssten. Wenn es Ihnen nichts ausmacht, was die Gründe für die Verwendung des Attributs "title" sind, sehe ich es nicht auf W3C w3schools.com/tags/tag_option.asp und kann mich nicht erinnern, es wirklich verwendet zu haben. Könnten Sie nicht einfach die Beschreibung in den Objekten speichern und dann trotzdem diese Daten abrufen, da das Modell jetzt daran gebunden ist?
Shaunhusain
Wenn Sie auf der von Ihnen verlinkten W3C-Seite auf den Link Globale Attribute klicken, wird das Titelattribut vom Optionselement unterstützt. Ich verwende das title-Attribut nur, um den "Tooltip" -Text anzuzeigen. Wenn Sie den Mauszeiger über eine Option bewegen, erhalten Sie eine ausführlichere Beschreibung der Bedeutung der Option. Es ist eine kleine Sache, aber es wäre schön, wenn möglich.
Charles O.
@ CharlesO. Ich möchte genau wie du tun. Legen Sie ein Objekt fest (Wert ohne Zeichenfolge), aber ich möchte auch einen Titel in der Optionsliste verwenden. Gibt es dafür eine Lösung? Ich kann es nicht finden ...
Wilt
1

Wenn Sie die md-select- und ng-repeat-md-Option aus eckigem Material verwenden, können Sie ng-model-options="{trackBy: '$value.id'}"die in diesem Stift angezeigte md-select-Tag-Asche hinzufügen

Code:

<md-select ng-model="user" style="min-width: 200px;" ng-model-options="{trackBy: '$value.id'}">
  <md-select-label>{{ user ? user.name : 'Assign to user' }}</md-select-label>
  <md-option ng-value="user" ng-repeat="user in users">{{user.name}}</md-option>
</md-select>

Japheth Ongeri - inkalimeva
quelle