Winkel, boolescher Wert in einem Auswahlfeld

70

Ich möchte einen booleschen Wert mit einer Auswahl auf wahr oder falsch setzen. Hier ist mein Code:

<select class="span9" ng-model="proposal.formalStoryboard">
<option value="false">Not Included</option>
<option value="true">Included</option>
</select>

Der Wert (comment.formalStoryboard) wird ordnungsgemäß auf true oder false gesetzt , die Änderung wird jedoch nicht im Auswahlfeld angezeigt, wenn der Wert bereits zugewiesen ist.

Ich habe versucht, ng-value = "true" und ng-value = "false" anstelle von nur value, aber es funktioniert auch nicht.

Jerome Ansia
quelle
ngValue funktioniert gut für mich (getestet auf Angular 1.6)<select ng-model="$ctrl.request.invoiced" class="form-control input-lg"> <option ng-value="undefined">All</option> <option ng-value="false">Not Invoiced</option> <option ng-value="true">Invoiced</option> </select>
Stefan Norberg

Antworten:

86

EDIT: Kommentatoren haben darauf hingewiesen, dass meine ursprüngliche Lösung nicht wie behauptet funktioniert hat. Ich habe die Antwort aktualisiert, um die korrekte Antwort anderer unten wiederzugeben (ich kann eine akzeptierte Antwort nicht löschen).

Betrachten Sie für Angular 1.0.6 diesen HTML-Code:

<div ng-app="">
  <div ng-controller="MyCntrl">
    <select ng-model="mybool"
            ng-options="o.v as o.n for o in [{ n: 'Not included', v: false }, { n: 'Included', v: true }]">
    </select>
    <p>
        Currently selected: <b>{{ mybool }}</b> opposite: {{ !mybool }}
   </p> 
 </div>
</div>

Und dieses JavaScript:

function MyCntrl($scope) {
    $scope.mybool = true;
}

Hier ist eine funktionierende DEMO für Angular 1.0.6 und hier ist eine funktionierende DEMO für Angular 1.3.14, die sich geringfügig unterscheidet.

ChrisP
quelle
Hallo Chris, ich habe diesen Teil zum Laufen gebracht, ich habe das Problem in meiner Frage fett geschrieben :)
Jerome Ansia
@ Jerome Ansia: Siehe Kommentar / Antwort von sza. Sie haben nicht gepostet, was Ihr Problem verursacht. Dieser Code funktioniert.
ChrisP
oh ok gib mir ein paar Minuten, ich werde das überprüfen;)
Jerome Ansia
@ JeromeAnsia, ist der Code, den Sie in einem Element mit ng-repeatoder in einer benutzerdefinierten Direktive gepostet haben ? Ich vermute, dass das <select>in einem anderen Bereich existiert.
ChrisP
3
Das funktioniert eigentlich nicht. Ich habe Ihre jsfiddle aktualisiert, um auch die Umkehrung anzuzeigen : jsfiddle.net/jGfL5/14 Dies setzt den Wert tatsächlich auf die Zeichenfolge "true" oder die Zeichenfolge "false", die beide als wahr ausgewertet werden.
Boushley
58

Mach einfach so:

<select ng-model="someModel" ng-options="boolToStr(item) for item in [true, false]">
</select>

und definieren:

$scope.boolToStr = function(arg) {return arg ? 'Included' : 'Not included'};
ricofe25
quelle
1
nette Antwort, die einzige, die wirklich den schwierigen Teil der Frage
anzusprechen
24
Um zu vermeiden, dass boolToStr definiert wird, habe ich ng-options = "ov wie für o in [{n: 'Nein', v: falsch}, {n: 'Ja', v: wahr}]"
Aaron
Danke übrigens für diese Antwort! IMO ist dies der beste Weg, um dieses Problem zu lösen.
Aaron
@ Aaron Funktioniert das richtig für dich? Ich versuche es (mit Angular 1.3) und obwohl es richtig angezeigt wird, erhalte ich einen großen Fehler in meinem Stack-Trace, wenn die var-Deklaration inline ist. Wenn ich ein Options-Array im Controller definiere und es durchschleife, funktioniert es einwandfrei. Ich habe mich gefragt, ob Sie die gleichen Probleme hatten.
Eric B.
@EricB. Es funktioniert für mich inline, ohne dass ein Fehler gedruckt wird, und ich verwende v1.3.0-beta.2. Wenn Sie das Problem in einem Plunkr reproduzieren können, werde ich sehen, ob ich beim Debuggen helfen kann.
Aaron
34

Warum nicht einfach das benutzen?

<select class="form-control" ng-options="(item?'Included':'Not Included') for item in [true, false]"></select>
Thiago Passos
quelle
2
Nett. Speichert Boolesche Werte (nicht Strings) wie gewünscht im Modell und alles in einer Zeile. Es besteht wirklich keine Notwendigkeit für eine Direktive oder eine Hilfsfunktion.
Joeytwiddle
9

Wenn Sie die AngularJS-Version verwenden >= 1.2.0, haben Sie Zugriff auf die Direktiveng-value

Sie können das ng-valueOptionselement on verwenden. Ihre htmls würden so funktionieren.

<select ng-model="proposal.formalStoryboard">
    <option ng-value="true">Included</option>
    <option ng-value="false">Not Included</option>
</select>

Es funktioniert auch mit Radio und Kontrollkästchen.

Kieran
quelle
3
Dies ist die einfachste Antwort, die funktioniert. Bestätigt ab Juni 2018
Felipe
leicht und einfach
Nitsan Baleli
Das sollte akzeptiert werden oder zumindest die am besten bewertete Antwort!
Nikzin
Ich schätze die Abstimmung. Es sieht so aus, als ob ngValue erst in Version 1.2.0 verfügbar wurde. Sie können also verstehen, warum dies nicht die akzeptierte Antwort ist
Kieran
2

Ich würde empfehlen, hierfür eine Direktive zu verwenden. Wie üblich versuche ich, mich von Zeitüberschreitungen und anderen asynchronen Vorgängen fernzuhalten, anstatt eine autoritativere und direktere Kontrolle zu bevorzugen.

directives.directive('boolean', function() {
  return {
    priority: '50',
    require: 'ngModel',
    link: function(_, __, ___, ngModel) {
      ngModel.$parsers.push(function(value) {
        return value == 'true' || value == true;
      });

      ngModel.$formatters.push(function(value) {
        return value && value != 'false' ? 'true' : 'false';
      });
    }
  };
});

Die Priorität wird speziell so festgelegt, dass sie vor anderen Anweisungen ausgeführt wird (für die normalerweise keine Priorität festgelegt ist, und standardmäßig) 0 ).

Zum Beispiel verwende ich diese Direktive (für eine True / False-Auswahl) mit meiner selectpickerDirektive, die meine selectElemente in die einschließtselectpicker Bootstrap-Plugin einschließt.

Bearbeiten:

Die Einschränkung hier, die ich vergessen habe zu erwähnen, ist, dass Ihre HTML-Werte Zeichenfolgenwerte sein müssen. Die Direktive übersetzt zwischen der Ansicht und dem Modell, wobei der Modellwert booleanund Ihre Ansicht im stringFormat bleiben:

%select.selectpicker{ ng: { model: 'modelForm.listed' }, selectpicker: '{ }', boolean: true }
  %option{ value: 'true' } Listed
  %option{ value: 'false' } Unlisted
Volte
quelle
2

Das wird auch funktionieren. Erzwingen Sie einfach, dass der Wert boolesch ist, indem Sie einen Winkelausdruck für den Wert eingeben.

<select class="span9" ng-model="proposal.formalStoryboard">
    <option value="{{false}}" 
           ng-selected="proposal.formalStoryboard === false">
           Not Included
    </option>
    <option value="{{true}}"
            ng-selected="proposal.formalStoryboard === true">
            Included
    </option>
</select>
suh
quelle
Es funktioniert für mich, aber der Wert von ng model hat den Typ string. In meiner Variante danach habe ich SignalR und es macht einen booleschen Typ für c #, aber in vielen Fällen löst es das Problem nicht.
Константин Золин
1

Ich habe ein Beispiel für Sie erstellt. Bitte überprüfen Sie dies .

Möchten Sie das Modell verwenden, um die UI-Bindung zu steuern?

<div ng-app ng-controller="Ctrl">
    <select class="span9" ng-model="proposal.formalStoryboard">
        <option value="false">Not Included</option>
        <option value="true">Included</option>
    </select>
    <button ng-click="changeValue();">Click</button>
<div>

function Ctrl($scope) {
    $scope.proposal = {};
    $scope.proposal.formalStoryboard = true;

    $scope.changeValue = function () {
        $scope.proposal.formalStoryboard = !$scope.proposal.formalStoryboard;
        console.log($scope.proposal.formalStoryboard);
    }
}
zs2020
quelle
3
Ihr Beispiel hat einen subtilen Fehler. Wenn Sie mit select einen Wert auswählen, wird die Zeichenfolge festgelegt. Wenn Sie das Auswahlfeld in "Nicht enthalten" ändern, klicken Sie auf die Schaltfläche "Klicken". Der Wert wird daher nicht geändert. Dies liegt daran, dass die Zeichenfolge "false" auf den Wert false verschoben wurde.
Boushley
0

Ich hatte sehr wenig Erfolg mit diesem frustrierenden Problem. Meine Lösung ist zwar nicht zu elegant, da es sich um eine zusätzliche Codezeile handelt, hat sie jedoch jedes Mal gelöst. Dies funktioniert möglicherweise nicht in jeder Anwendung.

$scope.myObject.myBooleanProperty = $scope.myObject.myBooleanProperty.toString();

Durch die Umwandlung in eine "echte" Zeichenfolge vor dem Versuch, sie wieder an das auf der Seite angezeigte Modell zu binden, konnte der Wert korrekt ausgewählt werden.

Tony Basallo
quelle
0

Angular führt einen strengen Vergleich zwischen der Wertbindung an das ng-Modell und den Werten in den angegebenen Optionen durch. Die in der ersten Frage angegebenen Werte sind die Zeichenfolgen "falsch" und "wahr". Wenn der Wert von ng-model vom Typ bool ist und wie {"Wert": false} definiert ist, stimmt Angulars strict === Vergleich zwischen Zeichenfolge und Bool niemals überein, sodass das Auswahlfeld leer ist.

Das eigentliche Problem ist: Wenn Sie einen Wert auswählen, kann der von bool in string ({"Wert": false} -> {"Wert": "false"}) geänderte Typ Fehler verursachen, wenn er zurückgesendet wird.

Die beste Lösung für beide Probleme war für mich die von Thiago Passos in diesem Beitrag. ( https://stackoverflow.com/a/31636437/6319374 )

zlit
quelle
-3
<script type='text/javascript'>
function MyCntrl($scope) {<!--from   ww w . j  a  v a 2s.  c om-->
  $scope.mybool = true;
}

</script>
</head>
<body>
  <div ng-app="">
  <div ng-controller="MyCntrl">
    <select ng-model="mybool">
        <option value="false">Not Included</option>
        <option value="true">Included</option>
    </select>
    <p>
    Currently selected: {{ mybool }}
   </p>
 </div>
</div>
</body>
</html>
Harendra
quelle
Dies ist nicht die Lösung des Problems und führt tatsächlich das gleiche Problem in die ursprüngliche Frage ein.
Bruno Finger