web-dev-qa-db-fra.com

La valeur initiale du modèle ng n'est pas définie dans select

J'ai un enum (je code en utilisant TypeScript):

export enum AddressType
{
    NotSet = 0,

    Home = 1,
    Work = 2,
    Headquarters = 3,

    Custom = -1,
}

Ensuite, dans mon contrôleur, j'ai un champ nommé type, dans lequel je spécifie la valeur initiale devant être sélectionnée dans l'entrée de sélection (je le règle sur AddressType.Headquarters).

Enfin, dans mon HTML je mets ce qui suit:

<select ng-model="Ctrl.type" ng-options="addressType for addressType in Ctrl.getAddressTypes()"></select>

Tout semble bien fonctionner, sauf une chose: pour une raison quelconque, Angular ne sélectionne pas initialement "3" (Siège social) dans la sélection après la mise à jour de toutes les liaisons. Angular crée une option supplémentaire comme celle-ci:

<option value="?" selected="selected"></option>

Donc, pour une raison quelconque, Angular ne peut pas comprendre l'option initiale à sélectionner dans la liste déroulante.

Si l'utilisateur sélectionne une autre option de la liste déroulante, Ctrl.type est mis à jour correctement pour que la liaison fonctionne correctement pour cette partie. Fondamentalement, mon problème est que l’option qui doit être sélectionnée initialement n’est pas sélectionnée comme prévu.

Qu'est-ce qui me manque ici qui cause ce problème?

21
sboisse

Trouvé le problème:

Le tableau renvoyé par Ctrl.getAddressTypes () était un tableau de chaînes:

["0", "1", "2", "3", "1"]

et ce qui était stocké dans Ctrl.type était de type number.

AngularJS compare le tableau fourni à ng-options à la valeur fournie à ng-model à l'aide de l'opérateur '==='. 3 ne correspond pas à "3" dans ce cas - c'est pourquoi cela n'a pas fonctionné.

32
sboisse

Je rencontre souvent ce problème lorsque j'utilise un identifiant numérique. Mon moyen de contourner ce problème est d’ajouter ''+ pour le convertir en type chaîne:

<select ng-options="''+u.id as u.name for u in users"
16
Will Stern

Dans une fonction, si le code ci-dessous est ajouté et appelé de la même manière à partir de ng-init, le problème est également résolu. Cela résoudra le problème de la comparaison des chaînes.

$scope.Ctrl.type = "" + $scope.Ctrl.type + "";
1
Pallab Bhowmik

Je arrive parce que vous n'avez pas initié la valeur sélectionnée. Essayez de définir la valeur init avec ng-init:

<select ng-model="Ctrl.type" 
       ng-options="addressType for addressType in Ctrl.getAddressTypes()"
       ng-init="Ctrl.type = ..."
       ></select>

Voir cette démo Fiddle où nous avons 2 combos avec et sans valeur init. Vous pouvez voir qu'un combo HTML ressemble à ceci:

<select ng-model="selectedItem1"
 ng-options="selectedItem1.name as selectedItem1.name for selectedItem1 in values" class="ng-pristine ng-valid">
   <option value="?" selected="selected"></option>
   <option value="0">General</option>
   <option value="1">Super</option>
   <option value="2">Trial</option>
 </select>

Le bon:

<select ng-model="selectedItem" 
        ng-options="selectedItem.name as selectedItem.name for selectedItem in values" 
        ng-init="selectedItem = values[1].name" class="ng-pristine ng-valid">
   <option value="0">General</option>
   <option value="1" selected="selected">Super</option>
   <option value="2">Trial</option>
</select>
0
Maxim Shoustin