web-dev-qa-db-fra.com

Façon correcte d'utiliser l'énumération TypeScript dans angular HTML (par exemple angular ng-class)

Nouveau dans angular et TypeScript.

J'ai l'énumération TypeScript comme suit

public enum MyEnum{
   A = 0,
   B = 1,
   C = 2
}

Une variable de portée

$scope.myLetter: MyEnum = MyEnum.B;

Quelle est la bonne façon de mettre le chèque enum?

Option 1: Comparez la valeur entière de enum dans la page html-

<div ng-class="{classA: myLetter === 0, classB: myLetter === 1, classC: myLetter === 2}">Test panel</div>

Option 2: Récupère le nom de classe à partir de la méthode de portée du contrôleur

$scope.getClass(value: myLetter): string{
    if(value === MyEnum.A)
    return 'classA';

    if(value === MyEnum.B)
    return 'classB';

    if(value === MyEnum.C)
    return 'classC';
}

Et pour avoir l'élément html as-

<div ng-class='getClass(myLetter)'>Test panel</div>

Option 3: réponse donnée par 'RyanNerd' à Angular.js et ng-switch-when - émulation enum

Pour moi, l'option 2 est préférable, les options restantes ont des vérifications dans la valeur de la classe ng sous forme de chaîne, ce qui ne nous donnera pas d'application de type statique. Veuillez partager vos opinions ou toute autre meilleure option si vous en avez.

24
Trans

Obtenez le nom de classe à partir de la méthode de portée du contrôleur

Je n'aime pas l'idée de faire en sorte que le contrôleur connaisse les noms de classe.

  1. Vous pouvez ajouter une fonction de convertisseur à la portée:

    $scope.myEnumName = (value: MyEnum) => MyEnum[value];
    

    et utilisez-le dans le modèle:

    ng-class="{'A':'ClassA', 'B':'ClassB', 'C':'ClassC'}[myEnumName(myLetter)]"
    
  2. Ou ajoutez une fonction de commutation

    $scope.switchMyEnum =
        <T>(value: MyEnum, cases: { [value: string]: T }) => cases[MyEnum[value]];
    

    modèle:

    ng-class="switchMyEnum(myLetter, {'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
    
  3. Si vous avez seulement besoin du commutateur myLetter:

    $scope.switchMyLetter =
        <T>(cases: { [value: string]: T }) => cases[MyEnum[$scope.myLetter]];
    

    modèle:

    ng-class="switchMyLetter({'A':'ClassA', 'B':'ClassB', 'C':'ClassC'})
    
  4. Si vous souhaitez utiliser plusieurs énumérations dans de nombreux domaines:

    angular.module("MyApp", [])
      .run(["$rootScope", (root: {}) => {
        function registerSwitchers(...enumInfos: [string, { [value: number]: string }][]) {
          enumInfos.forEach(enumInfo => {
            var switcherName = enumInfo[0]
            var enumType = enumInfo[1]
            root[switcherName] = (value: any, cases: { [value: string]: any }) => cases[enumType[value]];
          });
        }
        registerSwitchers(
          ["switchMyEnum1", MyEnum1],
          ["switchMyEnum2", MyEnum2]);
      }])
    
9
Artem

Vous pouvez également créer l'objet classe dans votre contrôleur et le définir comme expression (avec une notation entre crochets) dans votre vue.

Exemple:-

$scope.panelClass = {};
$scope.panelClass[MyEnum.A] = 'classA';
$scope.panelClass[MyEnum.B] = 'classB';
$scope.panelClass[MyEnum.C] = 'classC';

Vous pouvez écrire ce qui précède en tant que syntaxe abrégée (ES6), à condition que votre version TypeScript la prenne en charge (prend en charge le polyfill), de sorte que vous pouvez la réécrire en:

$scope.panelClass = {
    [MyEnum.A]:'classA',
    [MyEnum.B]:'classB', 
    [MyEnum.C]:'classC'
};

et l'utiliser comme:

<div ng-class="panelClass[myLetter]">Test panel</div>

Ceci est similaire à l'expression abrégée de classe ng:

<div ng-class="{0:'classA', 1:'classB', 2:'classC'}[myLetter]">Test panel</div>
2
PSL

Vous pouvez définir votre énumération dans le rootScope

angular
    .module('moduleName', [])
    .run(['$rootScope', function ($rootScope) {
        $rootScope.Enum = PathToEnum.Enum;
     }]);
  • pro: Il est facile à installer et vous pouvez l'utiliser partout (dans différents contrôleurs ou en vue)
  • contre: vous perdez l'auto-complétion et la vérification lors de la compilation

En vue

<div ngController="AController">
    <div class="class" ng-class="{$root.Enum.A: 'classA', $root.Enum.B: 'classB'}[valueInScope]">
    </div>
</div>
1
rdhainaut

Nous avons généralement besoin de Enums lorsque nous avons besoin que les valeurs numériques soient référencées explicitement. Dans le cas d'utilisation ci-dessus, je ne vois pas le cas d'utilisation explicite de l'utilisation de enums. Un tableau fonctionnerait très bien, comme démontré:

((): void => {

 var ClassConstant: string[] = ['classA', 'classB', 'classC'];
 
 angular
  .module('app', [])
  .constant('ClassConstant', ClassConstant)
  .controller('AppController', ($scope, ClassConstant) => {
          $scope.setClass = (classname: string) => {
                return ClassConstant[classname];
          };
  });
 })();
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.0/angular.min.js"></script>
  <meta charset="utf-8">
  <title>JS Bin</title>
</head>
<body ng-app="app">

  <div ng-controller="AppController">
    <div ng-class="{{setClass(myLetter)}}">1</div>
  </div>
  
</body>
</html>
1
Aditya Singh

J'ai également été confronté à cette question.

Voici ma solution:

Je crée une fonction dans le contrôleur qui retourne un booléen pour chaque valeur de mon énumération.

Dans mon controller.ts

export class AController { 
    public TestEnumA(): boolean { 
        return this.scope.field == MyEnum.A; 
    }

    public TestEnumB(): boolean { 
        return this.scope.field == MyEnum.B; 
    }
}

À mon avis.html

<div ngController="AController as controllerAlias">
    <div class="a-class" ng-class="{'classA-true': controllerAlias.TestEnumA(), 'classB-true': controllerAlias.TestEnumB()}"><div>
</div>

Pourquoi j'ai choisi cette solution?

De cette façon, je ne pas coder en dur la classe css dans le contrôleur (codé en dur la classe css dans votre contrôleur, ce n'est pas une bonne idée d'assurer la maintenabilité de la vue)

De cette façon, je ne pas coder en dur la valeur d'énumération dans votre classe ng;

De cette façon, je profite toujours de la complétion automatique du code ET du vérification lors de la compilation.

1
rdhainaut