web-dev-qa-db-fra.com

Valeur angulaire et booléenne dans une zone de sélection

Je veux définir une valeur booléenne à true ou false à l'aide d'une sélection, voici mon code:

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

La valeur (proposal.formalStoryboard) est correctement définie sur true ou false mais les modifications ne sont pas reflétées dans la zone de sélection lorsque la valeur est déjà attribuée.

J'ai essayé ng-value = "true" et ng-value = "false" au lieu de value mais cela ne fonctionne pas aussi bien.

61
Jerome Ansia

EDIT: Des commentateurs ont souligné que ma solution initiale ne fonctionnait pas comme prévu. J'ai mis à jour la réponse pour refléter la réponse correcte donnée par d'autres ci-dessous (je ne peux pas supprimer une réponse acceptée).

Pour Angular 1.0.6, considérons ce code HTML:

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

Et ce JavaScript:

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

Voici un DEMO fonctionnel pour Angular 1.0.6 et voici un DEMO pour Angular 1.3.14, légèrement différent.

76
ChrisP

Faites juste comme ça:

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

et définir:

$scope.boolToStr = function(arg) {return arg ? 'Included' : 'Not included'};
58
ricofe25

Pourquoi ne pas simplement utiliser ceci?

<select class="form-control" ng-options="(item?'Included':'Not Included') for item in [true, false]"></select>
32
Thiago Passos

Je ne sais pas quelle version d'angular est devenu compatible mais vous pouvez maintenant utiliser le ng-value sur un élément d'option Vos HTML fonctionneraient comme ceci.

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

Cela fonctionne aussi à la radio et dans les cases à cocher. 

3
Kieran

J'ai créé un échantillon pour vous, veuillez vérifier this out.

Est-ce ce que vous voulez utiliser model pour piloter la liaison de l'interface utilisateur?

<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);
    }
}
1
zsong

Je recommanderais d'utiliser une directive pour cela. Comme d'habitude, j'essaie d'éviter les délais d'attente et autres opérations asynchrones au profit d'un contrôle plus direct et plus autoritaire.

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';
      });
    }
  };
});

La priorité est définie de manière spécifique afin qu'elle soit effectuée avant toute autre directive (qui n'a généralement pas de priorité définie et dont la valeur par défaut est 0)

Par exemple, j'utilise cette directive (pour une sélection true/false) avec ma directive selectpicker qui encapsule mes éléments select dans le plug-in selectpicker bootstrap.

Modifier:

La mise en garde ici, que j'ai oublié de mentionner, est que vos valeurs html doivent être des valeurs de chaîne. Ce que la directive fait est la traduction entre la vue et le modèle, en conservant la valeur du modèle dans boolean et votre vue au format string:

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

Cela fonctionnera aussi. Forcez simplement la valeur à être booléenne en insérant une expression angulaire dans la valeur.

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

Angular effectue une comparaison stricte entre la valeur associée à ng-model et les valeurs des options données. Les valeurs données dans la question initiale sont les chaînes "false" et "true" . Si la valeur de ng-model est de type bool et définie comme {"Value": false}, Angulars strict === comparaison entre string et bool ne correspondent jamais, la sélection est donc vide. 

Le vrai problème est que si vous sélectionnez une valeur, le type modifié de bool en chaîne ({"Value": false} -> {"Value": "false"}) peut provoquer des erreurs s'il est renvoyé.

La meilleure solution pour ces deux problèmes a été pour moi celle de Thiago Passos dans cet article . ( https://stackoverflow.com/a/31636437/6319374 )

0
zlit

J'ai eu très peu de succès avec ce problème frustrant. Ma solution, bien que pas très élégante puisqu'il s'agit d'une ligne de code supplémentaire, l'a résolue à chaque fois. Cela peut ne pas fonctionner dans toutes les applications.

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

Le transformer en une "vraie" chaîne avant d'essayer de le réassocier au modèle affiché sur la page lui permettait de sélectionner correctement la valeur.

0
Tony Basallo